/* ============================================================
   DAYLIGHT — the Hayato design language
   ------------------------------------------------------------
   Loaded AFTER app.css so this palette wins the cascade.
   app.css keeps its 38 canonical token NAMES; this file
   re-points their VALUES at the Daylight system. Nothing here
   renames a token, so every unported module inherits the new
   look without being touched.

   THE IDEA. The brand site (public/hayato.html) alternates warm
   paper with one dark blue-grey ground (#111A20, under the
   Method section). Daylight keeps that alternation and gives it
   meaning:

       WARM  = your day     — paper, and the stone hero block
       COOL  = the club     — the nav rail, photos, your account
       RED   = the one action on the screen. Never decoration.

   CLUB VALUES DO NOT LIVE HERE. The two club-owned colours are
   --ink and --action; KH.applyBranding overwrites both at
   runtime from club settings (primary_color / accent_color).
   The values below are the platform's neutral defaults — they
   are what an unconfigured club gets, not Hayato constants.
   ============================================================ */

:root {
  /* ── The three grounds ─────────────────────────────────────── */
  --paper:  #EEF1F7;   /* the page — white with a breath of indigo */
  --stone:  #DEE4F0;   /* the light block ground */
  --ink:    #111A20;   /* the cool ground — the club (club-owned) */

  /* ── The one action (club-owned) ────────────────────────────
     --action is the fill. --action-deep is its text-safe twin for
     labels and links on light grounds; applyBranding recomputes
     it by darkening --action until it clears 4.5:1 on BOTH paper
     and stone, so any club's accent gets a legible variant. */
  --action:      #E5243A;
  --action-deep: #B91628;

  /* ── Canonical tokens, re-pointed ───────────────────────────── */
  --bg:        var(--paper);
  --bg-2:      var(--stone);
  --surface:   #F8FAFD;   /* a card is paper lifted, not a new colour */
  --surface-2: #FCFDFE;
  --side-bg:   var(--ink);

  /* Text as rgba, deliberately: these compose against whichever
     ground they land on. Baked hexes tuned for paper drop to
     4.28:1 on stone — the hero block would have failed AA. */
  --text:   #171E38;
  --text-2: rgba(23, 30, 56, 0.76);   /* body   — 6.99 paper / 6.51 stone */
  --text-3: rgba(23, 30, 56, 0.65);   /* labels — 4.91 paper / 4.66 stone */
  --text-4: rgba(23, 30, 56, 0.44);   /* faint — placeholders only, never a label */

  --border:   rgba(23, 30, 56, 0.14);
  --border-2: rgba(23, 30, 56, 0.26);
  --hair:     rgba(23, 30, 56, 0.09);

  /* Primary action stays ink — its quiet authority is the point.
     The red is spent once per screen, on --action. */
  --accent:        #171E38;
  --accent-2:      rgba(23, 30, 56, 0.82);
  --accent-warm:   var(--action);
  --accent-warm-2: var(--action-deep);
  --accent-glow:   rgba(229, 36, 58, 0.24);

  /* Status colours pulled onto the blue-grey axis so they read as
     part of this palette rather than borrowed from another one. */
  --green: #3F6B52;
  --red:   var(--action-deep);
  --amber: #8A6A1F;
  --blue:  #17677F;
  --green-tint: rgba(63, 107, 82, 0.12);
  --red-tint:   rgba(185, 22, 40, 0.10);
  --amber-tint: rgba(138, 106, 31, 0.13);
  --blue-tint:  rgba(31, 125, 156, 0.12);

  /* Daylight is a flat, printed system. Shadows are near-absent;
     separation comes from ground changes and hairlines. */
  --shadow-sm: 0 1px 1px rgba(23, 30, 56, 0.04);
  --shadow-md: 0 1px 2px rgba(23, 30, 56, 0.06);
  --shadow-lg: 0 6px 22px rgba(23, 30, 56, 0.10);

  /* Squarer than BroncoHub. The brand site has no rounded corners
     at all; a little radius keeps controls tappable-looking. */
  --r:   4px;
  --r-2: 6px;
  --r-3: 8px;

  /* ── Type ───────────────────────────────────────────────────
     DM Sans for everything latin; Noto Serif JP carries Japanese,
     where the brand voice is a serif. One family, four weights —
     the hierarchy comes from size and tracking, not from mixing
     faces. --font-jp is for pull-quotes and ja headlines. */
  --font-display: 'DM Sans', 'Noto Sans JP', system-ui, sans-serif;
  --font-body:    'DM Sans', 'Noto Sans JP', system-ui, sans-serif;
  --font-jp:      'Noto Serif JP', 'Noto Sans JP', serif;
}

/* ── The headline treatment ───────────────────────────────────
   The brand's signature, lifted from hayato.html: weight 400 at
   large size, tracked tight, set solid. It only works big — do
   not apply .hl below ~28px, where the negative tracking closes
   the counters. */
.hl,
.hero-title,
.dl-hl {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -0.055em;
  line-height: 0.98;
  text-wrap: balance;
}

/* Japanese never takes the latin tracking, and never sets solid:
   -0.055em collides kana and 0.98 clips ascenders. */
html[lang="ja"] .hl,
html[lang="ja"] .hero-title,
html[lang="ja"] .dl-hl {
  letter-spacing: normal;
  line-height: 1.28;
  font-family: var(--font-jp);
}

.dl-jp { font-family: var(--font-jp); font-weight: 400; line-height: 1.45; }

/* Eyebrow + chapter number: the structural pair. The number is
   only honest where the content is genuinely a sequence — the
   parent's screens are (today, the club, the money, what's next). */
.dl-eyebrow {
  font-size: 12px; font-weight: 600; letter-spacing: 0.21em;
  text-transform: uppercase; color: var(--text-3);
}
.dl-eyebrow--now { color: var(--action-deep); }
.dl-no {
  font-size: 11px; font-weight: 600; letter-spacing: 0.2em;
  color: var(--text-3); font-variant-numeric: tabular-nums;
}
html[lang="ja"] .dl-eyebrow { letter-spacing: normal; text-transform: none; }

.dl-chapter {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: var(--space-3);
}

/* ── Grounds as utilities ─────────────────────────────────────── */
.dl-stone { background: var(--stone); color: var(--text); }
/* --on-ink, not --paper: a club with a pale primary needs dark type on
   this ground. Same fix as the nav rail — every surface that
   sits on --ink reads its type colour from the same adaptive token. */
.dl-ink   { background: var(--ink);   color: var(--on-ink, var(--paper)); }
.dl-ink .dl-eyebrow,
.dl-ink .dl-no      { color: color-mix(in srgb, var(--on-ink, var(--paper)) 68%, transparent); }
.dl-ink .k,
.dl-ink .dl-meta    { color: color-mix(in srgb, var(--on-ink, var(--paper)) 70%, transparent); }
.dl-ink a           { color: var(--on-ink, var(--paper)); }

/* ── Heroes ───────────────────────────────────────────────────
   Two different things share a name in this codebase:

     .hero   every page. The warm stone block, no photograph.
             Photography is out of the app entirely (owner, 30 Aug):
             the club band that carried it on Home is removed, and
             the vertical club-name strip with it.

   hero.css keeps ownership of sizing (the fluid clamp) and the ja
   guards; this file only restates surface and type, so the two
   sheets do not fight over the same properties. */
/* .hero's surface and type live in hero.css, which already owned its
   sizing — one home per fact. Only the eyebrow's accent is stated
   here, because the action colour is this file's to define. */
.hero .hero-eyebrow { color: var(--action-deep); }

/* ── The nav rail carries the club's colour ───────────────────
   Every value mixes from --on-ink, which applyBranding sets to
   paper or ink by whichever has more contrast against the club's
   primary. So a club that picks a pale primary gets dark rail type
   instead of an unreadable nav. --on-ink falls back to paper for
   the platform default, which is dark. */
.sb {
  background: var(--ink);
  color: var(--on-ink, var(--paper));
  border-right: 0;
}
.sb-brand-text,
.sb-fam-name        { color: var(--on-ink, var(--paper)); }
.sb-brand-mark      { background: color-mix(in srgb, var(--on-ink, var(--paper)) 12%, transparent); color: var(--on-ink, var(--paper)); }
.sb-fam-role,
.sb-section-h       { color: color-mix(in srgb, var(--on-ink, var(--paper)) 66%, transparent); }
.sb-item            { color: color-mix(in srgb, var(--on-ink, var(--paper)) 74%, transparent); border-radius: var(--r); }
.sb-item:hover      { color: var(--on-ink, var(--paper)); background: color-mix(in srgb, var(--on-ink, var(--paper)) 7%, transparent); }
.sb-item.active     { color: var(--on-ink, var(--paper)); background: color-mix(in srgb, var(--on-ink, var(--paper)) 11%, transparent); }
.sb-item.active::before { background: var(--action); }
.sb-fam, .sb-foot, .sb-head { border-color: color-mix(in srgb, var(--on-ink, var(--paper)) 16%, transparent); }
.sb-foot-row        { color: color-mix(in srgb, var(--on-ink, var(--paper)) 74%, transparent); }
.sb-foot-row:hover  { color: var(--on-ink, var(--paper)); background: color-mix(in srgb, var(--on-ink, var(--paper)) 7%, transparent); }
.sb-burger          { color: var(--on-ink, var(--paper)); }

/* ── Tab bar: the club's ink (owner, 12 Sep) — on a phone the bar is the
   one piece of club chrome that is always on screen, and it must read as
   the club, not as the browser. Text on ink, active tab in the accent. ── */
body[class*="kh-view-"] #kh-tabbar {
  background: var(--ink);
  border-top: 1px solid color-mix(in srgb, var(--on-ink, var(--paper)) 14%, transparent);
  box-shadow: none;
}
.tabbar-item        { color: color-mix(in srgb, var(--on-ink, var(--paper)) 64%, transparent); }
.tabbar-item span   { font-size: 10px; font-weight: 600; letter-spacing: 0.1em; }
.tabbar-item:active { color: var(--on-ink, var(--paper)); }
.tabbar-item.active { color: var(--on-ink, var(--paper)); }
.tabbar-item.active::before { background: var(--accent-warm); }
/* The More sheet rises from the same ink bar; keep it paper for reading. */
html[lang="ja"] .tabbar-item span { letter-spacing: normal; }

/* ── Actions ───────────────────────────────────────────────────
   One red button per screen. .btn.primary is that button; every
   other affordance is an outline on the ground it sits on. */
.btn { border-radius: var(--r); font-family: var(--font-body); font-weight: 500; }
.btn.primary {
  background: var(--action);
  border-color: var(--action);
  color: #fff;
  font-weight: 600;
}
.btn.primary:hover { background: var(--action-deep); border-color: var(--action-deep); }
.btn.ghost {
  background: transparent;
  border: 1px solid var(--border-2);
  color: var(--text);
}
.btn.ghost:hover { background: rgba(23, 30, 56, 0.05); }
.dl-ink .btn.ghost { border-color: color-mix(in srgb, var(--on-ink, var(--paper)) 34%, transparent); color: var(--on-ink, var(--paper)); }
.dl-ink .btn.ghost:hover { background: color-mix(in srgb, var(--on-ink, var(--paper)) 9%, transparent); }

/* ── Seigaiha stays available but never behind the headline ──── */
body.pattern-seigaiha .hero { background-image: none; }

/* The vertical club-name strip that ran down the right edge was
   the previous club's heritage mark, set in its own display face. It is
   deleted outright now — markup, the code that filled it, and the
   layout note in login.js that claimed to compensate for it. Its
   rules survive in app.css but nothing renders the element. */

/* ── Entry screens ────────────────────────────────────────────
   Sign-in is the one action on the page, so it takes the action
   colour, exactly like "Sora is going" on the parent home. */
.login-submit {
  background: var(--action);
  border-color: var(--action);
  color: #fff;
  font-family: var(--font-body);
  font-weight: 600;
  letter-spacing: 0.02em;
  border-radius: var(--r);
}
.login-submit:hover { background: var(--action-deep); border-color: var(--action-deep); }
html[lang="ja"] .login-submit { letter-spacing: normal; }

/* ── Rail details that assumed a light sidebar ────────────────────
   Both of these were written when --side-bg was paper. On the ink
   rail they misfire: the head gradient is a near-white smear across
   the top of the nav, and the scrollbar thumb is dark-on-dark. */
/* The head carried a diagonal gradient wash from the BroncoHub sheet. A
   gradient is the one thing this palette never does — the brand site has
   none, and on a flat ink rail it read as a smudge across the top corner.
   Suppressed outright rather than re-tinted. */
.sb-head::after { display: none; }
.sb {
  scrollbar-color: color-mix(in srgb, var(--on-ink, var(--paper)) 28%, transparent) transparent;
  box-shadow: none;
}
.sb::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--on-ink, var(--paper)) 28%, transparent); }
.sb::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--on-ink, var(--paper)) 44%, transparent); }

/* ── Rail components written against a LIGHT sidebar ──────────────
   --side-bg was paper before Daylight, so every piece below picked a
   light-surface colour: a near-white identity card, --accent (ink) as
   a badge fill with --bg (paper) as its text, --text for names. On the
   ink rail each of those is dark-on-dark or a white slab. They are all
   restated here against --on-ink, so the rail inverts as one piece
   whichever primary a club chooses.

   `.sb-brand-text .top` needs the descendant selector specifically: a
   rule on `.sb-brand-text` alone loses to it and the club name stays
   invisible. */
.sb-brand-text .top { color: var(--on-ink, var(--paper)); }
.sb-brand-text .sub { color: color-mix(in srgb, var(--on-ink, var(--paper)) 66%, transparent); }

.sb-brand-mark {
  background: color-mix(in srgb, var(--on-ink, var(--paper)) 14%, transparent);
  color: var(--on-ink, var(--paper));
}

.sb-fam,
.sb-view-picker {
  background: color-mix(in srgb, var(--on-ink, var(--paper)) 8%, transparent);
  border-color: color-mix(in srgb, var(--on-ink, var(--paper)) 16%, transparent);
}
.sb-fam-av {
  background: color-mix(in srgb, var(--on-ink, var(--paper)) 16%, transparent);
  color: var(--on-ink, var(--paper));
}
.sb-fam-av--photo { background-color: transparent; border-color: color-mix(in srgb, var(--on-ink, var(--paper)) 45%, transparent); }
.sb-fam-name { color: var(--on-ink, var(--paper)); }

/* The role pill was a hardcoded rgba(196,81,32,…) — the Bronco orange,
   surviving as a literal. Its text also took --accent-warm, which is now
   the action red and measures 3.9:1 on ink. Neutral on the rail instead;
   the red is spent on actions, not on a status label. */
.sb-fam-role {
  background: color-mix(in srgb, var(--on-ink, var(--paper)) 14%, transparent);
  color: color-mix(in srgb, var(--on-ink, var(--paper)) 82%, transparent);
}
.sb-view-picker__label { color: color-mix(in srgb, var(--on-ink, var(--paper)) 66%, transparent); }
.sb-view-picker__pills { background: color-mix(in srgb, var(--on-ink, var(--paper)) 8%, transparent); }

.sb-section-h { color: color-mix(in srgb, var(--on-ink, var(--paper)) 66%, transparent); }
.sb-section-h:hover {
  background: color-mix(in srgb, var(--on-ink, var(--paper)) 7%, transparent);
  color: var(--on-ink, var(--paper));
}
.sb-item .badge {
  background: color-mix(in srgb, var(--on-ink, var(--paper)) 16%, transparent);
  color: var(--on-ink, var(--paper));
}
.sb-item.active .badge { background: var(--action); color: #fff; }
.sb-version { color: color-mix(in srgb, var(--on-ink, var(--paper)) 66%, transparent); }

/* ══════════════════════════════════════════════════════════════════
   THE HOME CHAPTERS
   ------------------------------------------------------------------
   Daylight's Home is three blocks, and the order is the argument:
     01 dl-day     warm stone — what is happening next
     02 dl-account ink — where they stand with the club
   They share hero.css's geometry tokens so all three bands and the
   .hero on every other page sit on ONE rhythm, rather than each
   inventing its own padding.
   ══════════════════════════════════════════════════════════════════ */
.dl-block {
  padding: var(--hero-pad-y) var(--hero-gutter);
}
.dl-block > * { max-width: var(--max-page); }

.dl-day__hl,
.dl-account__hl {
  font-size: var(--hero-title-size);
  margin: 0;
  text-wrap: balance;
}
.dl-day { background: var(--ink); }
/* Desktop: the hero ends on the sidebar's divider under the club identity
   (--sb-head-h is measured from .sb-head by family.js). */
@media (min-width: 901px) {
  .dl-day { box-sizing: border-box; height: var(--sb-head-h, auto); min-height: 0; padding-top: 16px; padding-bottom: 16px; display: flex; flex-direction: column; justify-content: center; overflow: hidden; }
  .dl-day .dl-chapter { margin-bottom: 4px; }
  .dl-day .dl-day__sub { margin: 4px 0 0; }
  .dl-day .dl-day__cta { margin-top: 10px; }
  .dl-day .dl-day__cta .btn { min-height: 40px; }
}
.dl-day__hl--hello { font-size: clamp(30px, 3.4vw, 44px); }
.dl-weather { display: inline-flex; align-items: center; gap: 8px; margin: 6px 0 4px; font-size: 14px; color: var(--paper); opacity: 0.9; }
.dl-weather__glyph { font-size: 18px; line-height: 1; }
.dl-weather__txt b { font-weight: 600; }
.dl-weather__place { opacity: 0.65; }
.dl-day .dl-day__hl { color: var(--paper); }
.dl-day .dl-day__sub { color: var(--paper); opacity: 0.75; }
.dl-day .dl-eyebrow { color: #9DC1D3; }
.dl-day--players .dl-day__hl,
.dl-day--players .dl-day__sub { max-width: 62%; }
/* Contained panel, not a band. Full-bleed ink across the page reads as a
   black strip: the ink is a large flat field with a little text stranded at
   the left edge, and no proportion holds it together. Inset, with its own
   padding and a fixed measure, the same colour reads as a considered block —
   which is exactly how the mock uses it, beside the roster rather than
   across the page. */
.dl-account {
  padding: var(--space-5) var(--space-5) var(--space-5);
  border-radius: 0;
  display: flex;
  flex-direction: column;
  min-height: 220px;
}
.dl-account__hl {
  font-size: clamp(26px, 2.6vw, 36px);
  margin-top: auto;
}

.dl-day__sub {
  font-size: var(--hero-sub-size);
  line-height: 1.55;
  margin: clamp(12px, 1.4vw, 18px) 0 0;
  max-width: 52ch;
}
.dl-day__cta {
  display: flex; flex-wrap: wrap; gap: var(--space-3);
  margin-top: clamp(16px, 2vw, 22px);
}

/* Notices belong to the same "today" story as the day block. Keeping the
   ground continuous avoids a pale stripe wedged between the day and kids;
   urgency is expressed by the inset status panel, not another full-width
   ground change. */
.dl-notices {
  padding-top: 0;
  padding-bottom: var(--space-4);
  background: var(--ink);
  color: var(--paper);
}
.dl-notices__inner > :first-child { margin-top: 0 !important; }
.dl-notices .fq-membership { margin-bottom: var(--space-3); }
.dl-notices .pill {
  background: color-mix(in srgb, var(--paper) 9%, transparent);
  border-color: color-mix(in srgb, var(--paper) 28%, transparent);
  color: color-mix(in srgb, var(--paper) 86%, transparent);
}
.dl-notices .fq-banner {
  margin-top: 0 !important;
  background: color-mix(in srgb, var(--paper) 8%, transparent) !important;
  border-width: 1px !important;
  border-color: color-mix(in srgb, var(--action) 72%, var(--paper)) !important;
  border-radius: var(--r) !important;
  color: var(--paper) !important;
  box-shadow: none;
}
.dl-notices .fq-banner .btn {
  background: var(--action) !important;
  border-color: var(--action) !important;
  color: #fff !important;
}
.dl-notices .fq-banner .btn:hover {
  background: var(--action-deep) !important;
  border-color: var(--action-deep) !important;
}

.dl-account__meta {
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: color-mix(in srgb, var(--on-ink, var(--paper)) 72%, transparent);
  margin: var(--space-3) 0 0;
  max-width: 52ch;
}
.dl-account__row {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--space-4);
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid color-mix(in srgb, var(--on-ink, var(--paper)) 20%, transparent);
}
.dl-account__row .k {
  font-size: var(--fs-sm);
  color: color-mix(in srgb, var(--on-ink, var(--paper)) 72%, transparent);
}
.dl-account__row .v {
  font-size: var(--fs-lg);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
}

/* The eyebrow's own scale, matched to the band it labels. */
.dl-day .dl-eyebrow,
.dl-account .dl-eyebrow { font-size: var(--hero-eyebrow-size); }


/* ══════════════════════════════════════════════════════════════════
   DE-CARDING
   ------------------------------------------------------------------
   Daylight has no cards. Separation comes from ground changes,
   hairlines and space — the way the brand site separates its
   sections. These are the shared containers every module builds
   with, so flattening them here converts the whole app rather than
   one screen at a time.
   ══════════════════════════════════════════════════════════════════ */

/* Right-rail panels and KPI tiles: were white slabs with an inset
   highlight and a drop shadow, floating on paper. Now they are simply
   regions of the page, marked off by a rule. */
.feed,
.stat-card {
  background: transparent;
  border: 0;
  border-top: 1px solid var(--border);
  border-radius: 0;
  box-shadow: none;
  animation: none;
}
/* The Bronco stat band floated its cards over the hero with a -48px
   lift. De-carded tiles are hairline-topped page regions, so that lift
   now drags a rule straight through the hero's own text. No overlap:
   the band starts where the hero ends. */
.stats-band { margin: 0 36px; }
@media (max-width: 720px) { .stats-band { margin: 0 20px; } }

/* ── Daylight segmented control ─────────────────────────────────────
   THE tab/filter row for every screen: flat labels on one shared
   hairline, the active segment in full ink with the club's red
   underline. Replaces red-filled chip buttons wherever screens adopt
   it (financials first; other modules migrate as they're touched). */
.dl-seg {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: var(--space-5);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--space-4);
}
.dl-seg__btn {
  appearance: none; background: none; border: 0; cursor: pointer;
  min-height: var(--tap-min);
  padding: var(--space-2) 0;
  font-size: var(--fs-sm); font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide); text-transform: uppercase;
  color: var(--text-3);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color var(--dur-fast) var(--ease-default);
}
.dl-seg__btn:hover { color: var(--text-2); }
.dl-seg__btn.on { color: var(--text); border-bottom-color: var(--action); }
.dl-seg__btn:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
html[lang="ja"] .dl-seg__btn { letter-spacing: normal; text-transform: none; }
/* Secondary row (a filter under a tab row): quieter voice, same bones. */
.dl-seg--sub { border-bottom-color: var(--hair, var(--border)); }
.dl-seg--sub .dl-seg__btn {
  text-transform: none; letter-spacing: normal;
  font-weight: var(--fw-medium); font-size: var(--fs-sm);
}

/* ── Teal takes a real job (2 Sept color review) ──────────────────
   The kit's second colour stops being decoration: informational and
   secondary links wear petrol teal, keeping red for THE action and
   giving the palette its second identity note. */
.section-link,
.cf-viewall,
.feed-action,
.acad-chip i { color: var(--blue); }

/* ── Hanko 判子 — the seal for signatures ─────────────────────────
   A signed thing is STAMPED, not check-marked. Vermilion double-ring
   with 済; unsigned shows a dashed 未 that asks to be filled. */
.hanko {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%; flex: 0 0 auto;
  border: 2px solid var(--action);
  color: var(--action);
  font: 600 15px/1 var(--font-jp);
  transform: rotate(-8deg);
  position: relative;
}
.hanko::after {
  content: ''; position: absolute; inset: 2px; border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--action) 40%, transparent);
}
.hanko--empty {
  border-style: dashed; border-color: var(--border-2);
  color: var(--text-3); transform: none;
}
.hanko--empty::after { display: none; }
.hanko--sm { width: 26px; height: 26px; font-size: 12px; border-width: 1.8px; }

/* ── Tategaki 縦書き — one vertical accent per surface ────────────
   The club's name down a block's edge, spine-style. Rendered only in
   the ja locale on parent surfaces (vertical latin is for book spines,
   not headers) — the gamecard carries its own always-on variant. */
.dl-tategaki {
  position: absolute; top: 16px; right: 16px; bottom: 16px;
  writing-mode: vertical-rl;
  font: 400 11px/1 var(--font-jp);
  letter-spacing: 0.35em;
  color: color-mix(in srgb, var(--on-ink, var(--paper)) 42%, transparent);
  border-right: 1px solid color-mix(in srgb, var(--on-ink, var(--paper)) 18%, transparent);
  padding-right: 7px;
  pointer-events: none;
}
.dl-day { position: relative; }
html[lang="ja"] .dl-day { padding-right: 52px; }

/* Kanji chapter ordinals (第一, 第二) take the serif voice. */
html[lang="ja"] .dl-no--kanji { font-family: var(--font-jp); font-size: 13px; letter-spacing: 0.1em; }

.feed-head {
  padding: var(--space-4) 0 var(--space-3);
  border-bottom: 1px solid var(--hair, var(--border));
}
.feed-head + * { padding-top: var(--space-2); }
.feed-item { padding-inline: 0; }
.stat-card { padding: var(--space-4) 0 var(--space-5); }

/* Empty states were a dashed box on a stone fill — a slab of furniture
   announcing that there is nothing to see. Quiet text says it better. */
.empty-state {
  border: 0;
  border-radius: 0;
  background: transparent;
  padding: var(--space-5) 0;
  margin-inline: 0;
  color: var(--text-3);
}

/* ── Daylight player card ───────────────────────────────────────────
   The Bronco trading card is retired on this surface: no bronze
   radials, no glass-blur chips, no glowing warm dot, no lift. The card
   stays BIG — 4/5, the photograph is the content — but the ground is
   the club's ink, an unphotographed child gets the kamon diamond
   instead of a watermark letter, and every chip is a flat hairline.
   All colour comes from --ink/--paper/--action, so applyBranding
   restyles it per club with zero code. */
.card {
  border-radius: 0;
  box-shadow: none;
  background: var(--ink);
}
.card:hover {
  transform: none;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--paper) 35%, transparent);
}
.card-photo.placeholder {
  background: linear-gradient(160deg,
    color-mix(in srgb, var(--ink) 84%, var(--paper)) 0%,
    var(--ink) 68%);
}
.card-photo.placeholder::before {
  /* The kamon diamond — the same mark the boot splash and crest slots
     wear — so a child without a photo looks deliberate, not missing. */
  content: '';
  position: absolute;
  width: 44%;
  aspect-ratio: 1;
  transform: rotate(45deg);
  border: 1px solid color-mix(in srgb, var(--paper) 30%, transparent);
  background: color-mix(in srgb, var(--paper) 5%, transparent);
}
.card-photo.placeholder::after {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 84px;
  letter-spacing: -0.02em;
  color: color-mix(in srgb, var(--paper) 82%, transparent);
}
.card-overlay {
  background: linear-gradient(to top,
    color-mix(in srgb, var(--ink) 96%, transparent) 0%,
    color-mix(in srgb, var(--ink) 68%, transparent) 55%,
    transparent 100%);
  padding: 56px 20px 20px;
}
.card-name {
  font-family: var(--font-display);
  font-weight: 400;                 /* the brand headline voice, not bold shout */
  font-size: 32px;
  letter-spacing: -0.04em;
  color: var(--paper);
}
html[lang="ja"] .card-name { font-family: var(--font-jp); letter-spacing: normal; font-weight: 600; }
.card-position {
  color: color-mix(in srgb, var(--paper) 68%, transparent);
  letter-spacing: 0.10em;
}
html[lang="ja"] .card-position { letter-spacing: normal; text-transform: none; }
.card-band {
  background: color-mix(in srgb, var(--ink) 72%, transparent);
  backdrop-filter: none;
  border: 1px solid color-mix(in srgb, var(--paper) 26%, transparent);
  border-radius: 0;
  color: color-mix(in srgb, var(--paper) 92%, transparent);
}
html[lang="ja"] .card-band { letter-spacing: normal; text-transform: none; }
.card-band .dot { background: var(--action); box-shadow: none; }
.card-jersey { color: color-mix(in srgb, var(--paper) 90%, transparent); text-shadow: none; }
.card-jersey .hash { color: color-mix(in srgb, var(--paper) 40%, transparent); }
.card-stat {
  background: color-mix(in srgb, var(--ink) 72%, transparent);
  backdrop-filter: none;
  border: 1px solid color-mix(in srgb, var(--paper) 20%, transparent);
  border-radius: 0;
  color: var(--paper);
}
.card-stat .dot.green { background: var(--green); }
.card-stat .dot.red   { background: var(--action); }
.card-stat .dot.amber { background: var(--amber); }
.card-journey { border-color: color-mix(in srgb, var(--paper) 45%, transparent); }

/* Section headings take the chapter vocabulary: the rule sits under a
   heading set in the brand voice rather than a bold card title. */
.section-title {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -0.04em;
}
html[lang="ja"] .section-title { font-family: var(--font-jp); letter-spacing: normal; }

/* The page body shares the chapters' gutter so full-bleed bands and
   inset content line up on one left edge instead of two. */
.content {
  padding-inline: var(--hero-gutter);
  padding-block: clamp(28px, 4vw, 48px) var(--space-9);
}

/* ══════════════════════════════════════════════════════════════════
   THE CREST, BLENDED INTO THE RAIL
   ------------------------------------------------------------------
   Club logos are uploaded as JPEGs with no alpha — Hayato's is a
   1000×1000 with a near-white (#FAFAFA) field. Dropped onto the ink
   rail that reads as a white sticker, which is what it looked like.
   Inverting turns that field near-black, and `screen` composites
   near-black as a no-op, so only the mark survives — a light crest
   sitting IN the rail rather than on a tile. On a pale rail the
   polarity flips: no invert, and `multiply` drops the white field.
   ══════════════════════════════════════════════════════════════════ */
.sb-brand-mark {
  background: transparent;
  border: 0;
  border-radius: 0;
  overflow: visible;
}
.sb-brand-mark img {
  filter: invert(1) grayscale(1) contrast(1.06);
  mix-blend-mode: screen;
  opacity: 0.78;
  transition: opacity var(--dur-fast) var(--ease-default);
}
.sb-brand:hover .sb-brand-mark img { opacity: 0.95; }

body.rail-light .sb-brand-mark img {
  filter: grayscale(1) contrast(1.06);
  mix-blend-mode: multiply;
}

/* No logo on file: the initial keeps a quiet disc so the wordmark still
   has an anchor, but it is a wash of the rail's own ink, not a slab. */
.sb-brand-mark:not(:has(img)) {
  background: color-mix(in srgb, var(--on-ink, var(--paper)) 12%, transparent);
  border-radius: var(--r);
}

/* ══════════════════════════════════════════════════════════════════
   ACTING AS — the access switcher
   ------------------------------------------------------------------
   Was a bordered card holding a pill-group inside a second tinted
   tray: three nested containers for four words, and the pills wrapped
   onto two rows. Daylight has no trays. It is now a labelled list in
   the nav's own vocabulary — same rows, same red active marker as the
   sidebar items — so switching hats reads as part of the navigation
   rather than a widget bolted above it.
   ══════════════════════════════════════════════════════════════════ */
.sb-view-picker {
  margin-top: var(--space-4);
  padding: var(--space-4) 0 0;
  background: transparent;
  border: 0;
  border-top: 1px solid color-mix(in srgb, var(--on-ink, var(--paper)) 16%, transparent);
  border-radius: 0;
}
.sb-view-picker__label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--on-ink, var(--paper)) 66%, transparent);
  margin-bottom: var(--space-2);
}
html[lang="ja"] .sb-view-picker__label { letter-spacing: normal; text-transform: none; }

.sb-view-picker__pills {
  display: flex;
  flex-direction: column;
  gap: 0;
  background: transparent;
  border-radius: 0;
  padding: 0;
}
.sb-view-pill {
  position: relative;
  flex: none;
  width: 100%;
  text-align: left;
  padding: var(--space-2) var(--space-3);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--on-ink, var(--paper)) 74%, transparent);
  background: transparent;
  border: 0;
  border-radius: var(--r);
  box-shadow: none;
}
html[lang="ja"] .sb-view-pill { letter-spacing: normal; text-transform: none; }
.sb-view-pill:hover {
  color: var(--on-ink, var(--paper));
  background: color-mix(in srgb, var(--on-ink, var(--paper)) 7%, transparent);
  box-shadow: none;
}
.sb-view-pill.active {
  color: var(--on-ink, var(--paper));
  background: color-mix(in srgb, var(--on-ink, var(--paper)) 11%, transparent);
  box-shadow: none;
}
/* The same 2px red rail the active nav item carries. */
.sb-view-pill.active::before {
  content: '';
  position: absolute;
  left: 0; top: 50%; transform: translateY(-50%);
  width: 2px; height: 60%;
  background: var(--action);
}


/* The rail is a column of stacked regions; the account panel leads it. */
.rail {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  align-self: start;
}
.rail .dl-account { margin-bottom: 0; }
.rail .feed { border-top: 1px solid var(--border); }
/* The panel already carries the ink ground, so its first rule would double
   the separation against the paper beside it. */
.rail .dl-account + .feed { border-top: 0; }

@media (max-width: 900px) {
  .dl-day--players .dl-day__hl,
  .dl-day--players .dl-day__sub { max-width: none; }
  /* Single column: the panel spans the gutter like the day block above it. */
  .dl-account { min-height: 0; padding: var(--space-5) var(--hero-gutter); }
  .dl-account__hl { margin-top: 0; }
}

/* ══════════════════════════════════════════════════════════════════
   PAGE HEADERS AND SECTION MARKERS — every module
   ------------------------------------------------------------------
   These four decorations are written once in app.css and appear
   on every screen in the app, so they are what makes each module look
   like BroncoHub no matter what else changes. All four spend the
   accent on ornament; Daylight spends it once per screen, on the
   thing you can act on.
   ══════════════════════════════════════════════════════════════════ */

/* 1. The headline's <em> was accent-coloured AND carried a gradient
      underline — "Club announcements." put a red word with a red rule
      directly above the page's real red button. One headline, one
      voice: the emphasis is the size and the tracking, not a colour. */
.hero-title em,
.chero-club em,
.dl-hl em {
  font-style: normal;
  color: inherit;
  background-image: none;
  padding-bottom: 0;
}

/* 2. A 4px accent bar before EVERY section title. Repeated down a page
      it stops reading as emphasis and starts reading as wallpaper —
      and it is the third red thing on a screen that should have one.
      The rule under .section-head already separates the section. */
.section-title::before { display: none; }

/* 3. The live pulse dot. A blinking indicator earns its place when
      something is genuinely live; in a static page header it is
      decoration, and animation inside a heading is a distraction the
      parent never asked for.
      NOT display:none — every module uses this span as the SEPARATOR
      between the two halves of its eyebrow ("Club · 0 posts" | "Latest"),
      so hiding it ran the words together. It becomes the separator it
      was already acting as. */
.hero-eyebrow .pulse {
  animation: none;
  width: auto; height: auto;
  min-width: 0;
  background: none;
  border-radius: 0;
  box-shadow: none;
  display: inline;
}
.hero-eyebrow .pulse::before {
  content: '·';
  margin: 0 0.6em;
  opacity: 0.55;
}

/* 4. Counts were solid ink pills — heavy furniture for a number that
      is usually 0 or 1, and on an empty page "Recent posts (0)" in a
      black pill draws the eye to the emptiest thing on screen. */
.section-title .count,
.feed-badge {
  background: transparent;
  color: var(--text-3);
  border: 0;
  border-radius: 0;
  padding: 0;
  min-width: 0;
  height: auto;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  letter-spacing: 0;
}
.section-title .count::before,
.feed-badge::before { content: '· '; }

/* The section head becomes the mock's marker: a title in the brand
   voice over a hairline, with the count trailing quietly. */
.section-head {
  align-items: baseline;
  border-bottom: 1px solid var(--border);
}


/* An empty state centred in a wide column is a card idiom — it reads as
   the contents of a box that is no longer drawn. Left-aligned, it sits in
   the page's own column like every other line of text. */
.empty-state { text-align: left; }

/* The eyebrow separator, replacing the <span class="pulse"> that modules
   were using as punctuation. A real separator, so it survives the pulse
   being retired and reads correctly in both scripts. */
.hero-eyebrow__sep { font-style: normal; }
.hero-eyebrow__sep::before { content: '·'; margin: 0 0.6em; opacity: 0.55; }

/* ══════════════════════════════════════════════════════════════════
   FORM FIELDS AND CONTAINERS
   ------------------------------------------------------------------
   .kh-label and .kh-input were referenced by add_player, lookup_login
   and reset_password but DEFINED NOWHERE — every field on those three
   screens rendered as raw unstyled HTML, labels running inline with
   their inputs. They match the .field pattern app.css already
   uses, so the two vocabularies now look the same.
   ══════════════════════════════════════════════════════════════════ */
.kh-label {
  display: block;
  margin: var(--space-4) 0 var(--space-2);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
}
html[lang="ja"] .kh-label { letter-spacing: normal; text-transform: none; }
.kh-label:first-of-type { margin-top: 0; }

.kh-input {
  display: block;
  width: 100%;
  padding: 11px 12px;
  background: var(--surface);
  border: 1px solid var(--border-2);
  border-radius: var(--r);
  font: inherit;
  font-size: 16px;   /* 16px prevents iOS zooming the page on focus */
  color: var(--text);
  transition: border-color var(--dur-fast) var(--ease-default),
              box-shadow var(--dur-fast) var(--ease-default);
}
.kh-input:focus {
  outline: none;
  border-color: var(--text);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--text) 12%, transparent);
}
textarea.kh-input { min-height: 84px; resize: vertical; line-height: 1.5; }

/* A plain content container. Several modules were using .card for this —
   but .card is the PLAYER PHOTO card and carries `aspect-ratio: 4/5`, so
   a short form stretched into an enormous empty slab. */
.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: var(--space-5);
}
.panel + .panel { margin-top: var(--space-4); }

/* The .field pattern's focus ring still used the pre-Daylight charcoal. */
.field > input:focus,
.field > select:focus,
.field > textarea:focus {
  border-color: var(--text);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--text) 12%, transparent);
}

/* ══════════════════════════════════════════════════════════════════
   THE IDENTITY CARD IS THE ROLE SWITCHER
   ------------------------------------------------------------------
   Owner's pick (1 Sep) over a dropdown row and icon segments. The old
   'Acting as' section spent five rail rows on a rare action and named
   the active role twice. Multi-role users get a chevron on the card;
   tapping unfolds the role list OUT of the card — shared border, no
   gap — so it reads as the card opening, not a second widget. Single-
   role users get an inert card and no switcher at all.
   ══════════════════════════════════════════════════════════════════ */
.sb-fam--switch { cursor: pointer; user-select: none; }
.sb-fam--switch:hover { background: color-mix(in srgb, var(--on-ink, var(--paper)) 11%, transparent); }
.sb-fam--switch:focus-visible {
  outline: 2px solid var(--action);
  outline-offset: 2px;
}
.sb-fam-chev {
  margin-left: auto;
  flex-shrink: 0;
  font-size: 11px;
  color: color-mix(in srgb, var(--on-ink, var(--paper)) 60%, transparent);
}
/* Open: the card and the list fuse into one shape. */
.sb-fam--open { border-radius: var(--r) var(--r) 0 0; border-bottom: 0; }
.sb-fam-roles {
  background: color-mix(in srgb, var(--on-ink, var(--paper)) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--on-ink, var(--paper)) 16%, transparent);
  border-top: 1px solid color-mix(in srgb, var(--on-ink, var(--paper)) 12%, transparent);
  border-radius: 0 0 var(--r) var(--r);
  padding: var(--space-1);
  display: flex;
  flex-direction: column;
}
.sb-fam-roles .sb-view-pill {
  display: flex; align-items: center; gap: 10px;
  text-transform: none;
  letter-spacing: normal;
  font-size: 13px;
}
.sb-fam-roles .ico {
  flex-shrink: 0; width: 16px; height: 16px;
  display: grid; place-items: center;
}
.sb-fam-roles .ico svg { width: 16px; height: 16px; }

/* ══════════════════════════════════════════════════════════════════
   PLAYER DETAIL DRAWER — the last bronze holdout
   ------------------------------------------------------------------
   The drawer hero still rendered BroncoHub's trading card: ember
   radials on warm brown, a 120px watermark initial, a bold stacked
   name, a red all-caps eyebrow in the head. Same retirement the
   roster card got: the ground is the club's ink, an unphotographed
   child wears the kamon diamond, the name takes the brand headline
   voice, and everything below prints on hairlines. All colour is
   --ink/--paper/--action, so applyBranding restyles it per club.
   ══════════════════════════════════════════════════════════════════ */

/* Head: the red eyebrow spent the screen's one red on a subtitle.
   Quiet label voice instead — red stays reserved for actions. */
.drawer-head .title { font-weight: var(--fw-semibold); letter-spacing: -0.03em; }
.drawer-head .sub {
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide);
  color: var(--text-3);
}
html[lang="ja"] .drawer-head .sub { letter-spacing: normal; text-transform: none; }

/* Hero: the cool ground is the club, not a bronze radial. */
.drawer-hero { background: var(--ink); }
.drawer-hero .placeholder {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 68px;
  letter-spacing: -0.02em;
  color: color-mix(in srgb, var(--paper) 85%, transparent);
  background: linear-gradient(160deg,
    color-mix(in srgb, var(--ink) 84%, var(--paper)) 0%,
    var(--ink) 68%);
}
.drawer-hero .placeholder::before {
  /* The kamon diamond — the mark the roster card, boot splash and
     crest slots wear — so no-photo reads deliberate, not missing. */
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  height: 54%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%) rotate(45deg);
  border: 1px solid color-mix(in srgb, var(--paper) 30%, transparent);
  background: color-mix(in srgb, var(--paper) 5%, transparent);
}
.drawer-hero .veil {
  background: linear-gradient(to top,
    color-mix(in srgb, var(--ink) 96%, transparent) 0%,
    color-mix(in srgb, var(--ink) 45%, transparent) 55%,
    transparent 100%);
}
.drawer-hero .badge-row { color: var(--paper); }
.drawer-hero .name {
  font-weight: 400;                /* the brand headline voice, not bold shout */
  letter-spacing: -0.04em;
  line-height: 1.04;
  color: var(--paper);
}
html[lang="ja"] .drawer-hero .name { font-family: var(--font-jp); font-weight: 600; letter-spacing: normal; }
.drawer-hero .jersey {
  font-weight: 400;
  letter-spacing: -0.02em;
  color: color-mix(in srgb, var(--paper) 92%, transparent);
}
.drawer-hero .jersey .hash { opacity: 1; color: color-mix(in srgb, var(--paper) 40%, transparent); }

/* Sections and rows: printed — quiet label over a hairline. */
.dr-section-h {
  font-family: var(--font-body);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide);
}
html[lang="ja"] .dr-section-h { letter-spacing: normal; text-transform: none; }
.kv { border-bottom-color: var(--hair); }
.kv .v { font-weight: var(--fw-medium); }

/* ══════════════════════════════════════════════════════════════════
   SIDEBAR — the crest-anchored rail (owner's reference, 3 Sep)
   ------------------------------------------------------------------
   BroncoHub's rail was a stack of furniture: brand chip beside a
   wordmark, a bordered identity card wearing a pill, a boxed picker.
   Retired as one piece. The new rail reads top to bottom as: the
   hats you can wear (small icons — a pure parent sees none), the
   club's crest front and centre the way the academy's banner leads
   with the mark, the club's name in the serif voice, the person
   underneath, then quiet full-bleed navigation. All colour flows
   from --ink/--on-ink/--action, so applyBranding repaints per club.
   ══════════════════════════════════════════════════════════════════ */

.sb-head {
  padding: 14px 16px 22px;
  text-align: center;
}

/* ── The role strip — one icon per hat, red underline on the worn one */
.sb-roles {
  display: flex;
  justify-content: center;
  gap: var(--space-1);
  margin-bottom: var(--space-4);
}
.sb-role-ico {
  position: relative;
  width: 36px; height: 36px;
  display: grid; place-items: center;
  background: transparent;
  border: 0;
  border-radius: var(--r);
  color: color-mix(in srgb, var(--on-ink, var(--paper)) 52%, transparent);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-default),
              background-color var(--dur-fast) var(--ease-default);
}
.sb-role-ico svg { width: 16px; height: 16px; }
.sb-role-ico:hover {
  color: var(--on-ink, var(--paper));
  background: color-mix(in srgb, var(--on-ink, var(--paper)) 8%, transparent);
}
.sb-role-ico:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.sb-role-ico.active { color: var(--on-ink, var(--paper)); }
.sb-role-ico.active::after {
  content: '';
  position: absolute;
  left: 50%; bottom: 2px;
  transform: translateX(-50%);
  width: 14px; height: 2px;
  background: var(--action);
}

/* ── The crest — a quiet disc, the mark blended into the rail ────── */
.sb-crest {
  width: 96px; height: 96px;
  margin: var(--space-2) auto var(--space-4);
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--on-ink, var(--paper)) 20%, transparent);
  background: color-mix(in srgb, var(--on-ink, var(--paper)) 6%, transparent);
  display: grid; place-items: center;
  padding: 16px;
  overflow: hidden;
}
/* Same polarity trick as the old brand mark: invert + screen drops the
   crest JPEG's white field on the ink rail; multiply on a pale rail. */
.sb-crest img {
  width: 100%; height: 100%;
  object-fit: contain;
  filter: invert(1) grayscale(1) contrast(1.06);
  mix-blend-mode: screen;
  opacity: 0.92;
}
body.rail-light .sb-crest img {
  filter: grayscale(1) contrast(1.06);
  mix-blend-mode: multiply;
}
.sb-crest-init {
  font-family: 'Lora', var(--font-jp), serif;
  font-size: 40px;
  line-height: 1;
  color: color-mix(in srgb, var(--on-ink, var(--paper)) 80%, transparent);
}

/* ── Identity under the crest ─────────────────────────────────────
   The club name takes Lora — the rail's own voice, a serif no other
   chrome uses, so the rail reads as the club's letterhead rather
   than app furniture. Ja headlines already own Noto Serif JP, which
   Lora falls through to. */
.sb-id { min-width: 0; }
.sb-id-club {
  font-family: 'Lora', var(--font-jp), serif;
  font-weight: 500;
  font-size: 18px;
  line-height: 1.3;
  color: var(--on-ink, var(--paper));
}
.sb-id-name {
  margin-top: var(--space-3);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: color-mix(in srgb, var(--on-ink, var(--paper)) 86%, transparent);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sb-id-sub {
  margin-top: 2px;
  font-size: var(--fs-xs);
  color: color-mix(in srgb, var(--on-ink, var(--paper)) 55%, transparent);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── Navigation — full-bleed rows, a solid block for the current page */
.sb-body { padding: var(--space-4) 0 var(--space-3); }
.sb-section + .sb-section { margin-top: var(--space-3); }
.sb-section-h {
  padding: 6px 22px 5px;
  font-size: 10px;
  font-weight: var(--fw-semibold);
  letter-spacing: 0.18em;
  border-radius: 0;
}
html[lang="ja"] .sb-section-h { letter-spacing: normal; text-transform: none; }
.sb-item {
  padding: 10px 22px;
  border-radius: 0;
  gap: 12px;
}
.sb-item.active {
  background: color-mix(in srgb, var(--on-ink, var(--paper)) 12%, transparent);
  color: var(--on-ink, var(--paper));
}
/* The red edge rides the block's full height — the daylight active
   marker, sized to the mock's solid-slab highlight. */
.sb-item.active::before {
  left: 0; top: 0;
  transform: none;
  margin-left: 0;
  width: 2px; height: 100%;
  border-radius: 0;
  background: var(--action);
}

/* ── Footer aligns to the same full-bleed edge ────────────────────── */
.sb-foot { padding: var(--space-3) 0; }
.sb-foot-row { padding: 10px 22px; border-radius: 0; }
.sb-version { padding: 0 22px; }

/* ══════════════════════════════════════════════════════════════════
   SETTINGS LINK ROWS — the quick-links list on Account
   ------------------------------------------------------------------
   Was a feed of emoji-in-a-circle avatars beside bold titles — the
   BroncoHub activity-feed furniture doing navigation's job. Daylight
   navigation is printed: a labelled line over a hairline, the arrow in
   teal (the informational colour), nothing filled. The whole row is a
   real <button>, so the tap target is the line, not a word in it.
   ══════════════════════════════════════════════════════════════════ */
.dl-linkrow {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--space-4);
  width: 100%; text-align: left;
  appearance: none; background: none; border: 0; cursor: pointer;
  padding: 13px 0;
  min-height: var(--tap-min);
  border-bottom: 1px solid var(--hair);
  font: inherit; color: var(--text);
}
.dl-linkrow:last-child { border-bottom: 0; }
.dl-linkrow .t { font-size: var(--fs-base); font-weight: var(--fw-medium); }
.dl-linkrow .d { font-size: 13px; color: var(--text-3); margin-top: 2px; line-height: 1.5; }
.dl-linkrow .arrow { color: var(--blue); flex-shrink: 0; }
.dl-linkrow:hover .t { color: var(--blue); }
.dl-linkrow:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* Mobile: the sidebar is a top bar with a burger — the ceremonial
   centered head would push content below the fold. Compact row:
   small crest, club name beside it, role icons trailing (before the
   burger's reserved 70px). The person's name/email step back — the
   drawer is navigation here, not a letterhead. */
@media (max-width: 900px) {
  .sb-head {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    text-align: left;
    padding-bottom: 12px;
  }
  .sb-crest {
    order: 1;
    width: 44px; height: 44px;
    padding: 7px;
    margin: 0;
    flex-shrink: 0;
  }
  .sb-crest-init { font-size: 20px; }
  .sb-id { order: 2; flex: 1; }
  .sb-id-club { font-size: 15px; line-height: 1.2; }
  .sb-id-name, .sb-id-sub { display: none; }
  .sb-roles { order: 3; margin: 0; }
  .sb-role-ico { width: 32px; height: 32px; }
}

/* ══════════════════════════════════════════════════════════════════
   PRIMITIVES SWEEP (3 Sep audit) — how things MOVE and SIT
   ------------------------------------------------------------------
   Daylight re-pointed the palette but left the Bronco-era physics:
   buttons that lift and scale on warm shadows, glass blurs, 999px
   pills, 80px modal shadows, a carded fixture tile with a gradient
   sheen, and eleven surviving orange literals. This block retires
   all of it at the source classes, so every module converts at once.
   Daylight is flat and printed: nothing lifts, nothing glows.
   ══════════════════════════════════════════════════════════════════ */

/* ── Buttons: recolored earlier, de-physical now ─────────────────── */
.btn:hover { transform: none; box-shadow: none; }
.btn:active { transform: none; filter: none; box-shadow: none; }
.btn.primary, .btn.primary:hover { box-shadow: none; transform: none; }
.btn.ghost { backdrop-filter: none; background: transparent; }
.btn.sm { border-radius: var(--r); }
.btn.danger { box-shadow: none; }
.btn.danger:hover { background: var(--action-deep); }
html[lang="ja"] .btn { letter-spacing: normal; text-transform: none; }

/* ── Toasts: the most-fired element in the app, still a pill ─────── */
.toast {
  border-radius: var(--r);
  box-shadow: var(--shadow-lg);
}

/* ── Form controls ────────────────────────────────────────────────
   16px inputs (the iOS zoom-on-focus fix daylight gave .kh-input but
   never the 236 .field uses); quiet labels in ja; and checkboxes/
   radios finally join a design system instead of OS blue. */
.field > input, .field > select, .field > textarea { font-size: 16px; }
html[lang="ja"] .field > label { letter-spacing: normal; text-transform: none; }
input[type="checkbox"], input[type="radio"] { accent-color: var(--accent); }

/* ── Overlay shells: modal, drawer, confirm — one quiet elevation ── */
/* app.css opens .modal at opacity 0 and lets the modalIn animation bring it
   to 1 — killing the animation left every modal invisible ("Edit details"
   showed nothing). Land it fully drawn instead. */
.modal { box-shadow: var(--shadow-lg); animation: none; opacity: 1; transform: translate(-50%, -50%); }
.modal-head, .modal-foot { border-radius: 0; }
.modal-head .title { font-weight: var(--fw-semibold); letter-spacing: -0.03em; }
.drawer { box-shadow: var(--shadow-lg); }
.ov-back { backdrop-filter: none; }
.kh-confirm-box { box-shadow: var(--shadow-lg); }
.kh-confirm-back { backdrop-filter: none; }

/* ── The fixture card: the last big carded container ─────────────
   Was a lifted surface tile wearing a diagonal sheen that the token
   re-point turned RED. De-carded like .feed/.stat-card: a hairline-
   topped region of the page. */
.fix {
  background: transparent;
  border: 0;
  border-top: 1px solid var(--border);
  border-radius: 0;
  box-shadow: none;
}
.fix:hover { transform: none; box-shadow: none; border-color: var(--border); }
.fix::before { display: none; }
.fix-date .month { color: var(--text-3); }

/* ── Pills: printed chips, not capsules ──────────────────────────── */
.pill { border-radius: var(--r); }
/* .pill.warm was red text on a hardcoded orange wash — the worst
   surviving colour pairing. It marks "attention" → amber family. */
.pill.warm { background: var(--amber-tint); color: var(--amber); }

/* ── Stat-card residue the de-carding missed ─────────────────────── */
.stat-card:hover { transform: none; box-shadow: none; }
.stat-card::before { display: none; }
.stat-card[onclick], [role="button"] { -webkit-tap-highlight-color: rgba(23,30,56,0.08); }
.stat-card[onclick]:active { box-shadow: none; }
.stat-card.static, .stat-card.static:hover { box-shadow: none; }
.stat-icon.orange { background: var(--amber-tint); color: var(--amber); }
.feed-action:hover { background: transparent; color: var(--text); }

/* ── Surviving orange literals, neutralized ──────────────────────── */
:root { --accent-deep: var(--ink); }   /* the oxblood partner, retired */
.feed-item-av.club { background: var(--ink); }
.feed-item-av.coach1, .feed-item-av.coach2 { background: var(--stone); color: var(--text-2); }
.kh-seg:hover { background: rgba(23,30,56,0.05); }
.kh-seg.active { box-shadow: inset 0 0 0 1.5px var(--accent); }
.kh-tabs { background: transparent; border: 0; border-radius: 0; padding: 0; }
.kh-tab:hover { background: rgba(23,30,56,0.05); }
.kh-tab.active { box-shadow: inset 0 0 0 1.5px var(--accent); background: transparent; }
.kh-tab.active .kh-tab-count { background: var(--accent); color: var(--paper); }
.kh-pending-callout {
  background: transparent;
  border: 0;
  border-top: 2px solid var(--action);
  border-radius: 0;
}
.plan-card .pcurrent { background: var(--stone); color: var(--text); }
.ta-table tbody tr.ta-top { background: var(--blue-tint); }
@keyframes kh-pulse-flash {
  0% { background: var(--stone); }
  100% { background: transparent; }
}

/* ── The hairline tag — Daylight's multi-facet filter ─────────────
   (owner's pick, 3 Sep). dl-seg stays THE pattern for exclusive
   tabs; facet filters (centre × category × status…) use these:
   flat square-cornered tags on a hairline, the active tag filled
   solid ink with paper text. Quiet, printed, nothing like the
   filled red chip rows they replace. */
.dl-tag-row {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.dl-tag-row .dl-tag-label {
  font-size: 11px; font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide); text-transform: uppercase;
  color: var(--text-3);
  min-width: 88px;
}
html[lang="ja"] .dl-tag-row .dl-tag-label { letter-spacing: normal; text-transform: none; }
.dl-tag {
  appearance: none; cursor: pointer;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 5px 12px;
  min-height: 30px;
  font-family: var(--font-body);
  font-size: var(--fs-sm); font-weight: var(--fw-medium);
  color: var(--text-2);
  transition: background-color var(--dur-fast) var(--ease-default),
              color var(--dur-fast) var(--ease-default),
              border-color var(--dur-fast) var(--ease-default);
}
.dl-tag:hover { border-color: var(--border-2); color: var(--text); }
.dl-tag:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.dl-tag.on {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--paper);
}

/* ── Card chapters (owner, 4 Sep) ───────────────────────────────────
   Parent pages read as one long sheet — a section rule alone doesn't
   separate the chapters. Each chapter sits in its own bordered card:
   the coach overview's panel recipe (border, --r-2, --surface-2)
   applied to the daylight pages. */
.dl-card {
  padding: clamp(16px, 2.5vw, 24px);
  border: 1px solid var(--border);
  border-radius: var(--r-2);
  background: var(--surface-2);
}
.dl-card > .section-head:first-child { margin-top: 0; }
/* The card's own border does the separating — no doubled top rule. */
.dl-card > .feed, .rail .dl-card .feed { border-top: 0; }
.dl-stack { display: flex; flex-direction: column; gap: var(--space-4); }
