/* ============================================================
   SÚIL — the gloss, as Eóin chose it on 7 September 2026.

   He went through all eleven side by side and the answer was one
   clean line: THE READING LAYER IS HIS, THE FLOATING LAYER IS SÚIL.
   Everything you read and plan with — the menu, the headings, the
   day rows, the labels, the cards, the buttons, the fields — went
   back to the hub exactly as it was. Everything that floats over
   the page, and the numbers you read at a glance on a match day,
   stayed Súil:

     8   the pop-up message      frosted glass
     9   a box over the page     glass edge and lift
     10  the touchline rail      a centred cluster
     11  big numbers             Big Shoulders

   So this file is now short, and every rule in it earns its place.
   Nothing here declares a colour, radius, shadow or duration that
   is not a var() from /static/tokens.css.
   ============================================================ */

/* ---------- 1. the material ----------
   Liquid Glass is a material for OVERLAP. It needs something moving
   underneath it or it is a tinted rectangle, and blurring a flat
   background costs a frame and buys nothing.

   The EDGE — a rim lit on the top-left, shaded on the bottom-right,
   over a soft lift — is what makes a panel read as a raised slab of
   glass. It works on any background and it is free.

   True blur is spent only where content genuinely passes underneath:
   the mobile top bar, the mobile drawer, a sheet, a toast.
   (design/SUIL_BRIEF_v1.md §2.7) */
.suil-lit{position:relative;isolation:isolate;}
.suil-lit::before,.toast::before,.tbf-rail::before{
  content:"";position:absolute;inset:0;border-radius:inherit;padding:1px;
  pointer-events:none;background:var(--rim);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
          mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
}

/* The desktop rail sits BESIDE the page, not over it — nothing behind it to
   refract, so it takes no blur. The drawer really does slide over the page. */
@media(max-width:860px){
  #sidebar.open{
    background:rgb(250 248 244 / var(--glass-a));
    -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));
            backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));
    box-shadow:var(--sh-lift-2);
  }
}
/* The one bar on a phone with the page running under it. */
.topbar-mobile{
  background:rgb(250 248 244 / var(--glass-a));
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));
          backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));
  border-bottom:1px solid var(--glass-line);
}

/* ---------- 2. a box that opens over the page (his pick: B) ----------
   The scrim is already the frosted layer; blurring the sheet on top of it
   would blur the blur. The sheet takes the edge and a deeper lift. */
/* REGRESSION, FIXED: .modal is its own scroll container (hub.html:383,
   max-height:88vh; overflow-y:auto), so the absolutely positioned ::before
   rim it used to carry covered the first screenful and then slid away with
   the content — the exact trap #main was given an inset shadow to avoid.
   Inset shadows paint on the border box and do not scroll, so the rim is now
   two of them: lit along the top, shaded along the bottom. */
.modal{
  position:relative;isolation:isolate;
  box-shadow:var(--sh-lift-2),
             inset 0 1px 0 rgba(255,255,255,.92),
             inset 0 -1px 0 rgba(35,33,29,.10);
}
.modal-overlay{
  background:rgba(25,25,20,.28);
  -webkit-backdrop-filter:blur(10px) saturate(120%);backdrop-filter:blur(10px) saturate(120%);
}

/* ---------- 3. the pop-up message (his pick: B) ----------
   It floats over what you were reading, so it is real glass — and ink-dark,
   because a message you must not miss is not a whisper. #toastRoot loses its
   translate: a transformed ancestor breaks the blur under its children. */
#toastRoot{left:0;right:0;transform:none;justify-content:center;}
/* REGRESSION, FIXED: this used to set position:relative on EVERY .toast. The
   hub's toast is a static child of #toastRoot and needs it — but the Players
   Hub toast (player.html:160) has no #toastRoot and centres itself with
   position:fixed + translateX(-50%). Forcing it to relative dropped it out
   of the overlay layer entirely, so students stopped seeing it float at all.
   Positioning is scoped to the hub; the material applies to both. */
#toastRoot .toast{position:relative;}
.toast{
  isolation:isolate;padding:12px 20px;
  background:rgb(35 33 29 / .82);
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));
          backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));
  box-shadow:var(--sh-lift-2);
}
.toast::before{
  background:linear-gradient(155deg,rgba(255,255,255,.42) 0%,rgba(255,255,255,.10) 40%,rgba(255,255,255,.02) 70%,rgba(255,255,255,.20) 100%);
}

/* ---------- 4. the touchline tool rail (his pick: B) ----------
   It was a 62x800 column with its tools in the top half and 500px of empty
   white under them. It now shrinks to its tools and rides at the centre,
   level with the hand already holding the iPad. It stays IN the layout
   rather than floating over the pitch, because a player token under a
   floating rail is a token you cannot drag. */
.tbf-rail{
  position:relative;isolation:isolate;align-self:center;height:auto;max-height:100%;
  border-radius:var(--r-lg);box-shadow:var(--sh-lift);
}
/* Anything nested inside a rounded panel takes the parent radius minus its
   inset — concentric, as Apple draws it, never an arbitrary second radius. */
.tbf-btn{border-radius:calc(var(--r-lg) - 5px);}

/* ---------- 5. big numbers (his pick: B) ----------
   The score and the clock, and nothing else. Big Shoulders is the numeral
   face the wordmark is drawn in, so the score and the name share bones. It
   is a headline face: it never appears at reading size. */
.gd-nums,.gd-clock-num{
  font-family:var(--display);font-weight:700;letter-spacing:0;
  font-variant-numeric:tabular-nums;
}
.gd-nums{font-size:42px;line-height:1;}
.gd-clock-num{font-size:30px;}

/* ---------- 6. the press ----------
   A control lights under the finger, at the point it was touched — ink on a
   pale control, light on a dark one. Two custom properties set on
   pointerdown; nothing here runs per frame. */
.btn,.tbf-btn,.icon-btn,.pill,.nav-btn,.nav-sub-btn,.seg button{--px:50%;--py:50%;}
.btn:active,.tbf-btn:active,.icon-btn:active,.pill:active,.nav-btn:active,.nav-sub-btn:active,.seg button:active{
  background-image:radial-gradient(90px 90px at var(--px) var(--py),rgba(35,33,29,.10),transparent 62%);
}
.btn-primary:active{
  background-image:radial-gradient(90px 90px at var(--px) var(--py),rgba(255,255,255,.28),transparent 62%);
}
.btn,.nav-btn,.nav-sub-btn{transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease),transform var(--t-base) var(--spring);}
.btn:active{transform:scale(.985);}
.nav-btn:active,.nav-sub-btn:active{transform:scale(.99);}
.tbf-btn{transition:background var(--t-fast) var(--ease),transform var(--t-base) var(--spring);}
.tbf-btn:active{transform:scale(.96);}

/* ---------- 7. Sun mode ----------
   Bright daylight is the one place a translucent surface becomes a
   liability. Sun mode turns every frosted surface solid, thickens the
   hairlines, drops the lifts and stops the reveals. It is on the touchline
   rail, in the top bar and on the full-screen lineup sheet — the three
   places a coach can reach outdoors — and it is remembered, because a coach
   who needed it at 2pm on Saturday needs it again next Saturday. */
:root[data-sun="on"] #sidebar.open,
:root[data-sun="on"] .topbar-mobile,
:root[data-sun="on"] .modal-overlay,
:root[data-sun="on"] .toast{
  -webkit-backdrop-filter:none !important;backdrop-filter:none !important;
}
:root[data-sun="on"] .topbar-mobile,:root[data-sun="on"] #sidebar.open{background:var(--bg);}
:root[data-sun="on"] .modal-overlay{background:rgba(25,25,20,.45);}
:root[data-sun="on"] .toast{background:var(--ink);}
:root[data-sun="on"] .suil-lit::before,
:root[data-sun="on"] .toast::before,:root[data-sun="on"] .tbf-rail::before{display:none;}
:root[data-sun="on"] .card,:root[data-sun="on"] .tbf-rail{border:2px solid var(--line-2);box-shadow:none;}
:root[data-sun="on"] .enter{animation:none;}
:root[data-sun="on"] .btn:active,:root[data-sun="on"] .tbf-btn:active{transform:none;}
:root[data-sun="on"] .tbf-btn.on{box-shadow:inset 0 0 0 2px var(--accent-deep);}
:root[data-sun="on"] .tbf-stage svg{background:var(--surface);}
/* Daylight doubles the chalk — brief §2.3. The board reads this token, so
   the pitch goes to a darker line outdoors without touching a line of JS. */
:root[data-sun="on"]{--pitch-line:#6E6A61;}
/* The smallest type in the hub is the 9.5px rail label, not a token. It is
   the one word a coach squints at in sunlight, so the sun raises it. */
:root[data-sun="on"] .tbf-btn{font-size:11px;}
/* The Sun switch also lives in the top bar and on the lineup sheet, which
   hide the rail. Same lit state the rail buttons already use. */
.icon-btn.on,.btn.on{background:var(--accent-soft);color:var(--accent-deep);border-color:transparent;}

/* ---------- 8. the eye that opens ----------
   The mark blinks once while the hub reads its own data, then lifts. It is
   the only place the product animates its own name. The app is already
   rendered underneath it, so it never costs a coach a moment. */
#suilBoot{
  position:fixed;inset:0;z-index:9000;display:grid;place-items:center;
  background:var(--bg);transition:opacity var(--t-slow) var(--out);
}
#suilBoot>div{display:flex;flex-direction:column;align-items:center;}
#suilBoot.gone{opacity:0;pointer-events:none;}
/* If the script that lifts it never runs, the splash lifts itself. A coach is
   never locked out of the hub by its own front door. */
/* REGRESSION, FIXED: hub.html:456 is `@media (prefers-reduced-motion:
   reduce){*{animation:none !important}}`, which killed this four-second
   backstop for exactly the people most likely to need it. An id with
   !important outranks the universal selector, and a 1ms opacity flip used as
   a timer is not motion in the sense that preference is about. */
#suilBoot{animation:suil-boot-out 1ms linear 4s forwards !important;}
@keyframes suil-boot-out{to{opacity:0;visibility:hidden;pointer-events:none;}}
#suilBoot .eye{width:104px;color:var(--ink);}
#suilBoot .eye .lid{transform-box:fill-box;transform-origin:center;animation:suil-blink 2.2s var(--ease) 300ms infinite;}
#suilBoot .eye .iris,#suilBoot .eye .stub{transform-box:fill-box;transform-origin:center;animation:suil-iris 2.2s var(--ease) 300ms infinite;}
#suilBoot .eye .pupil{fill:var(--accent);}
#suilBoot .word{margin-top:16px;height:30px;color:var(--ink);opacity:0;animation:suil-word 500ms var(--out) 240ms both;}
#suilBoot .word svg{height:100%;width:auto;display:block;}
#suilBoot .word .fada{color:var(--accent-deep);}
@keyframes suil-word{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@keyframes suil-blink{0%,42%,100%{transform:scaleY(1)} 47%{transform:scaleY(.06)} 52%{transform:scaleY(1)}}
@keyframes suil-iris{0%,42%,100%{opacity:1} 46%,51%{opacity:0}}

/* ---------- 9. the floors ----------
   Motion is a courtesy, never load-bearing; contrast rises when the system
   asks; nothing frosted survives a contrast preference. */
@media (prefers-reduced-motion: reduce){
  #suilBoot .eye .lid,#suilBoot .eye .iris,#suilBoot .eye .stub,#suilBoot .word{animation:none;opacity:1;}
}
@media (prefers-contrast: more){
  .topbar-mobile{background:var(--bg);-webkit-backdrop-filter:none;backdrop-filter:none;}
  .toast{background:var(--ink);-webkit-backdrop-filter:none;backdrop-filter:none;}
  .toast::before,.tbf-rail::before{display:none;}
  .card,.tbf-rail{border-color:var(--line-2);}
}

/* ============================================================
   10. THE SECOND LOOK — the whole Súil reading layer, behind one
   attribute so the running app can be flipped between the two.

   Eóin chose the hub's own look from eleven side-by-side fragments,
   lived with it, and missed this one. The fragments were the wrong
   instrument: a condensed face in a 200px panel on a dark wall reads
   as loud, and the same face filling a real screen reads as
   confident. You cannot judge a typeface from a swatch, and a
   comparison that puts a familiar thing beside a stranger is always
   going to flatter the familiar thing.

   Nothing below touches the floating layer — that stayed Súil either
   way, and it is the same on both looks. This is the reading layer
   only, and it is one attribute on <html>.

   When he lands on one, the other gets deleted. An app does not
   need two looks forever.
   ============================================================ */
body{
  font-family:var(--body);
  font-optical-sizing:auto; font-kerning:normal;
  -webkit-font-smoothing:auto; letter-spacing:0;
}
input,
textarea,
select,
button{font-family:var(--body);}

/* The display face is a heading, not an announcement: 32px, not the poster
   size the brief allows, and never below 28px anywhere. */
.section h1{
  font-family:var(--display);font-weight:700;
  font-size:32px;line-height:1.04;letter-spacing:-.005em;margin:0;text-wrap:balance;
}
.section-sub{font-size:var(--fs-base);color:var(--ink-2);margin:4px 0 0;max-width:62ch;}
.section-head{align-items:flex-end;}
h2,h3{font-family:var(--body);letter-spacing:-.01em;}
.card-title{font-weight:var(--w-emph);font-size:var(--fs-md);letter-spacing:-.005em;}
.day-sum-title{
  font-family:var(--display);font-weight:700;font-size:24px;line-height:1.08;letter-spacing:-.005em;
}

/* The name. On this look the rail carries the wordmark; on the other it says
   Coaches Hub. The front door says Súil either way. */
.brand-title{
  font-family:var(--display);font-weight:700;font-size:26px;line-height:1;
  letter-spacing:-.01em;color:var(--ink);display:block;
}
.brand-title svg{height:26px;width:auto;display:block;}
.brand-title .fada{color:var(--accent-deep);}
.brand-badge{border-radius:var(--r-md);border-color:var(--line);box-shadow:none;}

/* The numbers a coach reads at a glance — the day on a calendar row, a count
   on a summary card. Nothing else: a face this condensed is a headline face,
   not an interface one. */
.call-num,
.glance-v,
.stat-val{
  font-family:var(--display);font-weight:700;font-variant-numeric:tabular-nums;letter-spacing:0;
}
.call-num{font-size:22px;line-height:1.05;}

/* Section labels are sentence case at reading size. */
.side-foot label{
  text-transform:none;letter-spacing:0;font-size:var(--fs-sm);
  font-weight:var(--w-emph);color:var(--ink-3);
}

/* Paper geometry: the content layer is rectangular, like a team sheet, and
   carries one cue per surface — a hairline or a shadow, never both. */
.card{border-radius:var(--r-md);box-shadow:none;border:1px solid var(--line);}
.card.hoverable:hover{box-shadow:var(--sh-1);transform:none;border-color:var(--line-2);}
.btn{border-radius:var(--r-sm);font-weight:var(--w-emph);letter-spacing:0;}
/* One tinted action per screen, and it does not glow. */
.btn-primary{background:var(--accent-deep);color:var(--on-accent);box-shadow:none;}
.btn-primary:hover{background:var(--accent);}
.nav-btn.active{font-weight:var(--w-emph);}
.team-switch-btn{border-radius:var(--r-md);}

/* ============================================================
   11. THE FLOATING SHELL — the thing the prototype screenshots
   actually show, which is not a typeface.

   In those pictures the rail is a rounded card and the page is a
   rounded card, both sitting on the paper with a gap around them,
   and the screen name rides above the content as a floating pill.
   That is a STRUCTURE difference, not a style one, and it is the
   single biggest reason the prototype felt like its own thing.

   It is also Eóin's own rule applied to the shell: on this look the
   rail and the page float, so they take the material — and the top
   bar finally has content passing underneath it, which is the first
   time real glass has a job on a desktop screen in this app.

   Desktop only. Below 861px the drawer and the mobile top bar keep
   the behaviour they already have.
   ============================================================ */
@media(min-width:861px){
  #app{
    background:var(--surface-2);
    padding:var(--s-3);gap:var(--s-3);min-height:100vh;
  }
  #sidebar{
    position:sticky;top:var(--s-3);height:calc(100vh - var(--s-3) * 2);
    background:var(--bg);border-right:0;border-radius:var(--r-lg);
    box-shadow:var(--sh-lift);isolation:isolate;
  }
  #sidebar::before{
    content:"";position:absolute;inset:0;border-radius:inherit;padding:1px;
    pointer-events:none;background:var(--rim);
    -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
            mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
    -webkit-mask-composite:xor;mask-composite:exclude;
  }
  /* #main scrolls, so its edge is an inset shadow rather than a ::before —
     an absolutely positioned rim inside a scroller only covers the first
     screenful and then slides away with the content. */
  #main{
    height:calc(100vh - var(--s-3) * 2);
    background:var(--bg);border-radius:var(--r-lg);
    box-shadow:var(--sh-lift),inset 0 0 0 1px var(--line);
  }

  /* The screen name becomes a floating pill over the page, the way it does
     in the prototype. It reuses the top bar that already exists on phones,
     so this is a display rule, not new furniture: the hamburger and the
     crest drop away, because on a desktop the rail is already there. */
  .topbar-mobile{
    display:flex;position:sticky;top:0;z-index:30;
    margin:var(--s-3) var(--s-3) 0;padding:8px 16px;
    width:max-content;max-width:calc(100% - var(--s-3) * 2);
    border:0;border-radius:var(--r-capsule);
    background:rgb(250 248 244 / var(--glass-a));
    -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));
            backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));
    box-shadow:var(--sh-lift);isolation:isolate;
  }
  .topbar-mobile::before{
    content:"";position:absolute;inset:0;border-radius:inherit;padding:1px;
    pointer-events:none;background:var(--rim);
    -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
            mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
    -webkit-mask-composite:xor;mask-composite:exclude;
  }
  .topbar-mobile [data-act="sidebar.open"],
  .topbar-mobile .brand-badge{display:none;}
  /* The page starts under the pill rather than beside it. */
  .section{padding-top:var(--s-5);}
}

/* Sun mode flattens the shell with everything else: solid panels, thicker
   hairlines, no lift, no frost. */
:root[data-sun="on"] #sidebar::before,
:root[data-sun="on"] .topbar-mobile::before{display:none;}
:root[data-sun="on"] #sidebar,
:root[data-sun="on"] #main{
  box-shadow:none;border:2px solid var(--line-2);
}
:root[data-sun="on"] .topbar-mobile{
  background:var(--bg);box-shadow:none;border:2px solid var(--line-2);
}

/* ---------- 11b. the rail, the headline and the labels ----------
   The rest of what the prototype screenshots actually show, once the
   floating shell is there. All of it is style; none of it moves a
   feature or a word. */
@media(min-width:861px){
  /* Nav rows in the prototype are things you could hit with a thumb on an
     iPad, not a desktop list: taller, bigger icons, more air. The current
     item is a white card with the accent standing at its left edge. */
  nav .nav-btn,
  nav .nav-sub-btn{
    min-height:44px;padding:8px 12px;font-size:var(--fs-md);gap:12px;margin-bottom:2px;
  }
  nav .nav-btn svg{width:20px;height:20px;}
  nav .nav-btn.active{
    position:relative;padding:8px 12px;border:0;border-radius:var(--r-md);
    background:var(--surface);box-shadow:var(--sh-1);
  }
  nav .nav-btn.active::after{
    content:"";position:absolute;left:0;top:9px;bottom:9px;width:3px;
    border-radius:var(--r-capsule);background:var(--accent);
  }
  .brand{padding:20px 16px 12px;}
  .team-switch-btn{min-height:40px;font-size:var(--fs-base);}

  /* The headline carries the screen. At 44 it is the size the prototype uses
     and the size a condensed face wants; below 28 it would be slower to read
     than the text under it, which is the whole reason to use it at all. */
  .section h1{font-size:44px;line-height:1;letter-spacing:-.01em;}
}

/* The label over a list: the words stay as they are — sentence case would
   mean rewriting eleven strings, which is copy and not gloss — but the
   shouting comes out of them. Tracking down from .14em, weight down, and a
   hairline underneath so it reads as the head of a list rather than a shout. */
.eyebrow{
  letter-spacing:.06em;font-weight:var(--w-emph);color:var(--ink-3);
  padding-bottom:8px;border-bottom:1px solid var(--line);
}
:root[data-sun="on"] .eyebrow{border-bottom-color:var(--line-2);border-bottom-width:2px;}

/* ---------- 11c. the five days as a row ----------
   The one layout idea worth taking from the prototypes. They show the week
   as five cards across; the hub shows it as five rows down. Across is simply
   better here: the whole week lands in one glance instead of a scroll, and it
   is not "less content" — it is the same content using the width the page
   already has.

   Pure CSS on the markup that is already there. .home-list appears once, on
   home, so nothing else can catch this. Below 1000px it falls back to the
   list it has always been, because five columns at that width is five
   slivers. */
@media(min-width:1000px){
  .home-list{
    display:grid;grid-template-columns:repeat(5,minmax(0,1fr));
    gap:var(--s-3);max-width:none;align-items:start;
  }
  .home-list .call-row{
    flex-direction:column;margin-bottom:0;gap:var(--s-2);min-width:0;
  }
  .home-list .call-date{
    width:auto;text-align:left;padding-top:0;
    display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;
  }
  .home-list .call-dow{
    text-transform:uppercase;letter-spacing:.06em;
  }
  .home-list .call-num{
    font-family:var(--display);font-weight:700;font-size:34px;line-height:1;
  }
  .home-list .call-today{margin-top:0;}
  .home-list .call-cards{gap:var(--s-2);}
  /* A card in a column is read top to bottom, so the time and the title stop
     competing for the same line. */
  .home-list .call-card{padding:12px;}
  .home-list .call-card-top{gap:4px;}
}

/* ============================================================
   12. THE DARK RAIL — the Léargas direction, wearing Súil's name.

   Eóin's call: "go back to the liquid glass leargas direction but
   with the Suil branding and animations". Léargas's signature was a
   dark rail with condensed uppercase nav against a light page. That
   is what this is. The name, the mark, the blinking eye and the
   press all stay Súil.

   It keeps the floating shell — a dark card on light paper rather
   than a flush column — because he asked for the liquid glass
   version of the direction, and a rail that floats is the one that
   has an edge to catch the light.

   Contrast is computed, not eyeballed: 15.3:1 for rail text, 7.9:1
   for secondary, 7.1:1 for the accent. The page's own green is only
   3.7:1 on this ground, which is why the rail carries its own.
   ============================================================ */
#sidebar{
  background:var(--rail);color:var(--on-rail);
  border-right:0;box-shadow:var(--sh-lift-2);
}
:root[data-theme="dark"] #sidebar::before{
  background:linear-gradient(155deg,rgba(255,255,255,.28) 0%,rgba(255,255,255,.07) 34%,rgba(0,0,0,.10) 66%,rgba(0,0,0,.20) 100%);
}

/* The name, in white, with the eye that is its fada in the rail's green. */
.brand-title{color:var(--on-rail);}
.brand-title .fada{color:var(--rail-accent);}
.brand-sub{color:var(--on-rail-2);}
.brand-badge{
  background:var(--rail-2);border-color:var(--rail-line);color:var(--on-rail);
}

/* Condensed uppercase nav — Léargas's real signature. Caps are read about a
   quarter faster at a glance, and these are six words a coach knows by shape
   rather than by reading. The display face earns its keep here. */
nav .nav-btn,
nav .nav-sub-btn{
  font-family:var(--display);font-weight:600;text-transform:uppercase;
  letter-spacing:.06em;color:var(--on-rail-2);
}
nav .nav-btn{font-size:19px;}
nav .nav-sub-btn{font-size:16px;}
nav .nav-btn svg{color:var(--on-rail-2);}
@media (hover:hover) and (pointer:fine){
  nav .nav-btn:hover,
  nav .nav-sub-btn:hover{background:var(--rail-2);color:var(--on-rail);}
}
nav .nav-btn.active,
nav .nav-sub-btn.active{
  background:var(--rail-on);color:var(--rail-on-ink);box-shadow:var(--sh-1);border:0;
}
nav .nav-btn.active svg{color:var(--rail-on-ink);}
nav .nav-btn.active::after{background:var(--rail-accent);}
/* A non-folder item like Home sits inside a .nav-folder that also carries
   .active, and that rule lands later than the one above — which painted the
   current item's label white on its own white pill. The folder rule is for
   the parent of an open group, so it now says so. */
.nav-folder.active>.nav-btn:not(.active){color:var(--on-rail);}
.nav-folder.active>.nav-btn:not(.active) svg:first-child{color:var(--rail-accent);}
.nav-folder .nav-chev{color:var(--on-rail-2);}

/* The squad switcher and the footer, on the dark. */
.team-switch-btn{
  background:var(--rail-2);color:var(--on-rail);border:1px solid var(--rail-line);
}
.team-switch-btn.active{background:var(--rail-on);color:var(--rail-on-ink);border-color:transparent;}
.side-foot{border-top-color:var(--rail-line);}
.side-foot label,
.who-role,
.sync{color:var(--on-rail-2);}
.who-name{color:var(--on-rail);}
.sync.saved::before{background:var(--rail-accent);}
.side-data button,
.side-data label.linklike,
.side-links a,
.signout{color:var(--on-rail-2);}
.side-data button:hover,
.side-data label.linklike:hover,
.side-links a:hover{color:var(--on-rail);}
.side-links{border-top-color:var(--rail-line);}
/* The press glow was ink on a pale control; on the rail it has to be light. */
.nav-btn:active,
.nav-sub-btn:active{
  background-image:radial-gradient(90px 90px at var(--px) var(--py),rgba(242,245,243,.16),transparent 62%);
}

/* The mobile drawer is the same rail, so it is dark there too — and it is
   the one place it genuinely floats over the page, so it keeps its blur. */
@media(max-width:860px){
  #sidebar{background:var(--rail);}
  #sidebar.open{
    background:color-mix(in srgb, var(--rail) 88%, transparent);
    -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));
            backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));
  }
}

/* Sun mode: the rail goes fully solid and loses its lift and its rim. A dark
   rail is already the high-contrast option outdoors, so it stays dark — it
   just stops being a lit object. */
:root[data-sun="on"] #sidebar{
  background:var(--rail);box-shadow:none;border:2px solid var(--rail-line);
}
:root[data-sun="on"] #sidebar::before{display:none;}
:root[data-sun="on"] #sidebar.open{
  background:var(--rail);-webkit-backdrop-filter:none;backdrop-filter:none;
}


/* ---------- 13. dark ----------
   Four surfaces in this file name a colour literally rather than through a
   token, because each is a translucency and there is no token for "the paper
   at 72%". Each one gets its dark twin here, and nothing else has to change:
   the rest of the app reads the palette. */
:root[data-theme="dark"] .topbar-mobile,
:root[data-theme="dark"] #sidebar.open{
  background:color-mix(in srgb, var(--bg) 78%, transparent);
  border-bottom-color:var(--glass-line);
}
:root[data-theme="dark"] .toast{
  background:color-mix(in srgb, var(--surface-3) 86%, transparent);color:var(--ink);
}
:root[data-theme="dark"] .toast::before{
  background:linear-gradient(155deg,rgba(255,255,255,.26) 0%,rgba(255,255,255,.07) 40%,rgba(0,0,0,.10) 70%,rgba(0,0,0,.22) 100%);
}
:root[data-theme="dark"] .modal-overlay{background:rgba(0,0,0,.52);}
:root[data-theme="dark"] .modal{
  box-shadow:var(--sh-lift-2),
             inset 0 1px 0 rgba(255,255,255,.16),
             inset 0 -1px 0 rgba(0,0,0,.34);
}
:root[data-theme="dark"] #app{background:#0B0D0F;}
:root[data-theme="dark"] #suilBoot{background:var(--bg);}
:root[data-theme="dark"] .tbf-stage svg,
:root[data-theme="dark"] .dz-flycard{background:var(--surface);}
/* Sun mode is an OUTDOOR switch and it outranks dark: nobody reads a dark
   screen in daylight. Turning it on puts the app back on paper. */
:root[data-sun="on"][data-theme="dark"]{
  --bg:#FAF8F4; --surface:#FFFFFF; --surface-2:#F5F3F0; --surface-3:#EAE5DB;
  --ink:#23211D; --ink-2:#5A564E; --ink-3:#6E6A61; --turf:#3F8F60;
  --line:#EAE5DB; --line-2:#DFD8CB;
  --accent:#008852; --accent-deep:#005C32; --accent-soft:#E6F2EB;
  --accent-rgb:0,136,82; --on-accent:#FFFFFF;
  --rail:#E7EFE9; --rail-2:#DCE7DF; --rail-line:rgba(21,32,26,.10);
  --on-rail:#1B2A22; --on-rail-2:#55655C; --rail-accent:#005C32;
  --pitch-line:#6E6A61;
  color-scheme: light;
}


/* ============================================================
   14. THE FRONT DOOR — the first sixty seconds.

   A coach with no squad yet gets one screen and one field. No
   rail, no dashboard, no tour: the hub is not a place he has to
   learn before it is worth anything, it is a box he pastes an
   address into. Then his own players' faces are on a pitch.

   One reveal per state. The only motion is the squad arriving,
   because that is the thing worth announcing. Contrast on paper,
   computed: headline 15.2:1, the line under it 6.9:1, the note
   5.1:1, the error 5.6:1, the number tag 8.2:1 on white.
   ============================================================ */
body.door-on #app{
  display:block;background:var(--bg);padding:0;gap:0;
}
.door{
  min-height:100vh;min-height:100dvh;
  display:grid;place-items:center;
  padding:var(--s-5) var(--s-4) var(--s-7);
}
.door-in{
  width:100%;max-width:560px;margin:0 auto;text-align:center;
}
.door-in.wide{max-width:900px;}
.door-in.enter{animation:door-rise var(--t-slow) var(--out) both;}
@keyframes door-rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* The mark, then the name — the same pair the boot splash draws, at rest.
   The eye has already blinked by the time a coach reads this. */
.door-head{display:flex;flex-direction:column;align-items:center;gap:var(--s-3);margin-bottom:var(--s-5);}
.door-mark{width:74px;color:var(--ink);}
.door-mark svg{display:block;width:100%;height:auto;}
.door-mark .pupil{fill:var(--accent);}
.door-word{height:26px;color:var(--ink);}
.door-word svg{display:block;height:100%;width:auto;}
.door-word .fada{color:var(--accent-deep);}

.door-h{
  font-family:var(--display);font-weight:800;
  font-size:clamp(38px,7vw,64px);line-height:1.04;letter-spacing:-.01em;
  color:var(--ink);margin:0;
}
.door-sub{font-size:var(--fs-md);color:var(--ink-2);margin:var(--s-2) 0 0;}
.door-note{font-size:var(--fs-base);color:var(--ink-3);margin:var(--s-3) 0 0;}
.door-err{font-size:var(--fs-base);color:var(--red);margin:var(--s-3) 0 0;}

/* One field and one button, side by side above 560 and stacked below it.
   The field is 52px because it is the only control on the screen. */
.door-form{
  display:flex;gap:var(--s-2);margin-top:var(--s-5);
}
.door-url{
  flex:1;min-width:0;height:52px;padding:0 var(--s-4);
  border:1px solid var(--line-2);border-radius:var(--r-sm);
  background:var(--surface);color:var(--ink);
  font-size:var(--fs-md);line-height:52px;
}
.door-url::placeholder{color:var(--ink-3);}
.door-url:focus{outline:none;border-color:var(--accent);box-shadow:var(--ring);}
.door-go{height:52px;padding:0 var(--s-5);font-size:var(--fs-md);flex:none;}
.door-skip{margin-top:var(--s-5);}
@media(max-width:560px){
  .door-form{flex-direction:column;}
  .door-go{width:100%;justify-content:center;}
}

/* The squad, as faces. This is the whole product in one view, so it is the
   only thing on the screen with any weight: the ring every player wears is
   the same ring the mark's iris is drawn as. */
.door-squad{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(88px,1fr));
  gap:var(--s-4) var(--s-2);
  margin:var(--s-5) 0 0;
}
.door-player{margin:0;display:flex;flex-direction:column;align-items:center;gap:var(--s-2);}
.door-face{
  width:58px;height:58px;border-radius:50%;overflow:hidden;
  background:var(--surface-2);border:3px solid var(--accent);
  display:grid;place-items:center;box-sizing:border-box;
  font-size:var(--fs-md);font-weight:var(--w-emph);color:var(--ink-2);
}
.door-face.gk{border-color:var(--gold);}
.door-face img{width:100%;height:100%;object-fit:cover;object-position:50% 12%;display:block;}
.door-player figcaption{
  font-size:var(--fs-sm);color:var(--ink-2);line-height:1.3;
  display:flex;align-items:center;gap:4px;max-width:100%;
}
.door-num{
  font-variant-numeric:tabular-nums;font-weight:var(--w-emph);
  color:var(--accent-deep);
}
.door-do{
  display:flex;flex-direction:column;align-items:center;gap:var(--s-3);
  margin-top:var(--s-6);
}

/* Sun mode: the door is already paper and ink, so it only loses its lift and
   doubles the one hairline it has. */
:root[data-sun="on"] .door-url{border-width:2px;}

/* The door again, smaller, inside the Squad screen. Same field, same button,
   no wordmark — the coach already knows where he is. */
.door-panel{max-width:640px;padding:var(--s-5);}
.door-panel.wide{max-width:none;}
.door-panel .door-in{text-align:left;max-width:none;}
.door-panel.wide .door-in{text-align:center;}
.door-h.sm{font-size:clamp(28px,4vw,38px);}
.door-panel .door-form{margin-top:var(--s-4);}
.door-other{
  display:flex;gap:var(--s-2);flex-wrap:wrap;margin-top:var(--s-4);
}

/* ============================================================
   THE WALK-IN — a head coach's first four steps, on the door.
   Same paper, same headline, same one button. The rail says where
   he is and how short it is; nothing else is added.
   ============================================================ */
.wl-rail{
  list-style:none;margin:0 auto var(--s-6);padding:0;
  display:flex;justify-content:center;gap:var(--s-2);flex-wrap:wrap;
}
.wl-rail li{
  display:flex;align-items:center;gap:6px;
  font-size:var(--fs-sm);color:var(--ink-3);
  padding:6px 12px 6px 6px;border-radius:var(--r-capsule);
  border:1px solid var(--line);
}
.wl-rail li.on{color:var(--ink);border-color:var(--ink);font-weight:var(--w-emph);}
.wl-rail li.done{color:var(--ink-2);}
.wl-n{
  width:22px;height:22px;border-radius:50%;display:grid;place-items:center;
  font-size:var(--fs-xs);font-variant-numeric:tabular-nums;
  background:var(--surface-2);color:var(--ink-2);
}
.wl-rail li.on .wl-n{background:var(--accent);color:var(--on-accent);}
.wl-rail li.done .wl-n{background:var(--accent-soft);color:var(--accent-deep);}

.wl-look{margin:var(--s-6) auto 0;max-width:440px;text-align:left;display:flex;flex-direction:column;gap:var(--s-2);}
.wl-crest{display:flex;align-items:center;gap:var(--s-4);margin-bottom:var(--s-4);}
.wl-badge{
  width:88px;height:88px;flex:none;border-radius:var(--r-md);
  border:1px solid var(--line-2);background:var(--surface);
  display:grid;place-items:center;overflow:hidden;
}
.wl-crest-do{display:flex;flex-direction:column;align-items:flex-start;gap:var(--s-1);}
.wl-crest-do .door-note,.wl-crest-do .door-err{margin:0;}
.wl-file{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;}
.wl-lab{font-size:var(--fs-sm);color:var(--ink-2);font-weight:var(--w-emph);margin-top:var(--s-3);}
.wl-in{width:100%;flex:none;}
.wl-swatches{display:flex;flex-wrap:wrap;gap:var(--s-2);}
.wl-sw{
  width:44px;height:44px;border-radius:50%;padding:0;cursor:pointer;
  background:var(--c);border:3px solid var(--surface);
  box-shadow:0 0 0 1px var(--line-2);position:relative;
}
.wl-sw.on{box-shadow:0 0 0 2px var(--ink);}
.wl-own{display:grid;place-items:center;overflow:hidden;}
.wl-own span{color:var(--ink);background:var(--surface);border-radius:50%;width:22px;height:22px;display:grid;place-items:center;pointer-events:none;}
.wl-colour{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer;border:0;padding:0;}

.wl-panel{text-align:left;margin-top:var(--s-6);}
.wl-panel .card{margin-bottom:0 !important;}

.wl-staff{margin:var(--s-6) auto 0;max-width:560px;text-align:left;display:flex;flex-direction:column;gap:var(--s-3);}
.wl-add{display:flex;gap:var(--s-2);flex-wrap:wrap;}
.wl-add .wl-in{flex:1 1 160px;width:auto;}
.wl-addgo{height:52px;padding:0 var(--s-5);}
.wl-sent{
  border:1px solid var(--line);border-radius:var(--r-md);background:var(--surface);
  padding:var(--s-3) var(--s-4);display:flex;flex-direction:column;gap:var(--s-2);
}
.wl-who{display:flex;gap:var(--s-2);align-items:baseline;flex-wrap:wrap;}
.wl-who span{color:var(--ink-3);font-size:var(--fs-sm);}
.wl-link{display:flex;gap:var(--s-2);}
.wl-link input{
  flex:1;min-width:0;height:44px;padding:0 var(--s-3);
  border:1px solid var(--line-2);border-radius:var(--r-sm);
  background:var(--surface-2);color:var(--ink-2);font-size:var(--fs-sm);
}
.door.wl .door-do .door-note{margin:0;}
@media(max-width:560px){
  .wl-rail li{padding-right:8px;}
  .wl-add .wl-in,.wl-addgo{flex:1 1 100%;}
}

/* The wait between "these are my players" and the board. One bar, one pass,
   and it stops when the screen changes — nothing in this app animates
   forever. */
.door-wait{
  width:180px;height:3px;margin:var(--s-5) auto 0;
  background:var(--surface-3);border-radius:var(--r-capsule);overflow:hidden;
}
.door-wait span{
  display:block;width:40%;height:100%;border-radius:inherit;
  background:var(--accent);
  animation:door-wait 1.4s var(--ease) infinite;
}
@keyframes door-wait{
  from{transform:translateX(-110%)}
  to{transform:translateX(360%)}
}
@media (prefers-reduced-motion: reduce){
  .door-wait span{animation:none;width:100%;}
}


/* ============================================================
   15. THE MATERIAL, WITH A JOB — liquid glass, done Apple's way.

   Eóin, 7 Sep 2026: "use apple liquid glass as the key design
   feature… modern, clean, minimal, sexy."

   Apple's own rule is the one that makes it look expensive rather
   than cheap: glass is CHROME, never content, and it needs real
   content passing underneath or it is a picture of glass. So this
   section does two structural things and then gets out of the way:

     1. the page slides UNDER the rail, so the rail is genuinely
        refracting the squad's faces as they scroll past it;
     2. the screen's own header becomes the one floating bar, and
        the content runs under that too.

   That second one is also the biggest cut in the app: the desktop
   used to carry a floating screen-name pill AND a section heading
   saying the same thing. One header now. Two fewer surfaces, one
   more thing for the glass to do.
   ============================================================ */
@media(min-width:861px){
  /* No gap between rail and page: the page goes under the rail instead. */
  #app{gap:0;}
  #main{
    margin-left:calc(var(--s-5) * -1);
    padding-left:var(--s-5);
  }
  #sidebar{
    z-index:40;
    background:color-mix(in srgb, var(--rail) 76%, transparent);
    -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));
            backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));
    box-shadow:var(--sh-lift-2);
  }

  /* One header. The pill that used to float above the page said the same
     word as the heading underneath it. */
  .topbar-mobile{display:none;}
  .section{padding-top:0;}
  .section-head{
    position:sticky;top:0;z-index:26;
    margin:0 -34px var(--s-5);
    padding:var(--s-5) 36px var(--s-4);
    background:color-mix(in srgb, var(--bg) 66%, transparent);
    -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));
            backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));
    align-items:flex-end;
  }
  /* The scroll edge: a hairline that only appears once something has gone
     under the bar, so a page that fits on one screen has no furniture. */
  .section-head::after{
    content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;
    background:var(--line);opacity:0;transition:opacity var(--t-base) var(--ease);
  }
  .section.scrolled .section-head::after{opacity:1;}
}

/* ---------- 15b. the modes and the one colour ----------
   Three controls at the foot of the rail instead of two floating over every
   screen. The swatches are 28px rather than the app's 44 floor on purpose:
   the floor is for things a coach hits on a touchline in the rain, and this
   is a thing he sets once, indoors, sitting down. */
/* Eight controls in a 210px column do not fit on one line, and in the phone
   drawer the overflow leaked past the closed rail as a floating dot. They
   wrap. */
.side-modes{
  display:flex;align-items:center;gap:var(--s-2);flex-wrap:wrap;
  margin-bottom:var(--s-4);
}
.side-foot{overflow:hidden;}
.mode-btn{
  width:40px;height:40px;border-radius:var(--r-md);
  display:grid;place-items:center;flex:none;
  color:var(--on-rail-2);background:var(--rail-2);
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease),
             transform 250ms var(--spring);
}
.mode-btn.on{background:var(--rail-on);color:var(--rail-on-ink);}
.mode-swatches{display:flex;gap:2px;margin-left:auto;flex-wrap:wrap;}
.swatch{
  width:28px;height:28px;padding:4px;border-radius:50%;flex:none;
  background:var(--sw);background-clip:content-box;
  transition:transform 250ms var(--spring),box-shadow var(--t-fast) var(--ease);
}
.swatch.on{box-shadow:inset 0 0 0 2px var(--sw);}
@media (hover:hover) and (pointer:fine){
  .swatch:hover{transform:scale(1.14);}
  .mode-btn:hover{background:var(--rail-on);color:var(--rail-on-ink);}
}

/* ---------- 15c. the blink ----------
   The fada on the ú is an eye, and until now it was drawn in the same ink as
   the letters — the CSS coloured the group's `fill`, but the shapes inside
   name `currentColor`, so the one part of the identity that is meant to
   carry the team's colour never did. It does now, and it closes once when
   the app arrives, and again if you put a finger on the name. Once. Nothing
   in this app animates forever. */
.brand-title .fada .lid,
.door-word .fada .lid,
#suilBoot .word .fada .lid{transform-box:fill-box;transform-origin:center;}
.brand-title.blink .fada .lid,
.door-word.blink .fada .lid{animation:suil-fada 1400ms var(--ease) 1;}
.brand-title.blink .fada .pupil,
.door-word.blink .fada .pupil{animation:suil-fada-pupil 1400ms var(--ease) 1;}
@media (hover:hover) and (pointer:fine){
  .brand:hover .brand-title .fada .lid{animation:suil-fada 1400ms var(--ease) 1;}
  .brand:hover .brand-title .fada .pupil{animation:suil-fada-pupil 1400ms var(--ease) 1;}
}
@keyframes suil-fada{
  0%,46%,100%{transform:scaleY(1)}
  53%{transform:scaleY(.06)}
  60%{transform:scaleY(1)}
}
@keyframes suil-fada-pupil{
  0%,48%,100%{opacity:1}
  53%,58%{opacity:0}
}

/* ---------- 15d. the press ----------
   Apple's "illuminates from within": the control lights at the point touched
   and gives under the finger, 90ms down and a spring back up. The glow was
   already here; the give was not. */
.btn,.pill,.icon-btn,.mode-btn,.swatch,.nav-btn,.nav-sub-btn,.seg button{
  transition:background var(--t-fast) var(--ease),
             color var(--t-fast) var(--ease),
             box-shadow var(--t-fast) var(--ease),
             transform 250ms var(--spring);
}
.btn:active,.pill:active,.icon-btn:active,.mode-btn:active,
.nav-btn:active,.nav-sub-btn:active,.seg button:active{
  transform:scale(.97);transition-duration:90ms;
}
.swatch:active{transform:scale(.92);transition-duration:90ms;}

/* ---------- 15e. the squad arriving ----------
   The one place in the hub that earns a stagger, because it is the one
   moment the product is selling: a coach's own players appearing. 18ms
   apart and capped, so thirty-four faces land in half a second rather than
   parading past. Everywhere else, one reveal per screen, as decided. */
.door-squad .door-player{
  animation:door-face 320ms var(--out) both;
  animation-delay:calc(var(--i, 0) * 18ms);
}
@keyframes door-face{
  from{opacity:0;transform:scale(.94)}
  to{opacity:1;transform:none}
}
@media (prefers-reduced-motion: reduce){
  .door-squad .door-player{animation:none;}
}

/* ---------- 15f. sun mode, and the floors ----------
   Daylight takes the frost out of everything, including the two surfaces
   this section just made glass. */
:root[data-sun="on"] #sidebar,
:root[data-sun="on"] .section-head{
  -webkit-backdrop-filter:none !important;backdrop-filter:none !important;
}
:root[data-sun="on"] #sidebar{background:var(--rail);}
:root[data-sun="on"] .section-head{background:var(--bg);}
@media (prefers-contrast: more), (prefers-reduced-transparency: reduce){
  #sidebar,.section-head{
    -webkit-backdrop-filter:none;backdrop-filter:none;
  }
  #sidebar{background:var(--rail);}
  .section-head{background:var(--bg);}
}

/* The board's own header row. */
.lu-acts{display:flex;gap:var(--s-2);flex-wrap:wrap;align-items:center;}

/* The rail is a column: the nav is the part that scrolls, the brand and the
   footer are not. Without min-height:0 a flex child refuses to shrink and
   the nav pushed the footer over the last item instead of scrolling. */
#sidebar nav{min-height:0;}
#sidebar .brand,#sidebar .team-switch,#sidebar .side-foot{flex:none;}

/* The fada is the identity and it is six pixels tall on a 26px wordmark —
   large enough to draw, too small to read as an eye. The door is the one
   place the name is the whole screen, so it gets the size it deserves. */
.door-word{height:34px;}

/* When the nav is taller than the rail it scrolls, and a row cut in half by
   a hard edge reads as a bug. One soft fade says "there is more below"
   without adding a scrollbar or a chevron. The mask is on the nav, never on
   #sidebar itself — a mask on the glass element would collapse its blur. */
#sidebar nav{
  -webkit-mask-image:linear-gradient(#000 calc(100% - 20px), transparent);
          mask-image:linear-gradient(#000 calc(100% - 20px), transparent);
}

/* MEASURED BUG, dark mode: the current nav item was its own background.
   A non-folder door sits inside a `.nav-folder` that also carries `.active`,
   and hub.html's `.nav-folder.active>.nav-btn{color:var(--ink)}` is three
   classes deep — it outranks the rail's own `nav .nav-btn.active` rule, so
   the pill took the rail's light background and the page's light ink with
   it: #EEEBE4 on #F2F5F3, a contrast of 1.08:1. It was invisible in light
   mode only because there the page's ink happens to be dark. Five of the
   six doors are non-folders now, so this was every screen.
   Measured after the fix: 15.6:1. */
.nav-folder.active>.nav-btn.active{color:var(--rail-on-ink);}
.nav-folder.active>.nav-btn.active svg{color:var(--rail-on-ink);}
.nav-folder.active>.nav-btn.active::after{background:var(--rail-accent);}

/* ---------- 16. FEWER WORDS ----------
   The screen's own explanation lives behind its name. The mark is a quiet
   ring on the baseline of the title, not a blue circle-i: it reads as part
   of the headline until you want it, and it is 28px of target on a line
   that is already 44px tall. */
.section-name h1{display:flex;align-items:baseline;gap:var(--s-2);flex-wrap:wrap;}
.what{
  width:26px;height:26px;flex:none;align-self:center;
  border-radius:50%;border:1.5px solid var(--line-2);
  font-family:var(--body);font-size:var(--fs-sm);font-weight:var(--w-emph);
  line-height:1;color:var(--ink-3);
  display:inline-grid;place-items:center;
  transition:color var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease),
             background var(--t-fast) var(--ease),transform 250ms var(--spring);
}
.what:hover{color:var(--ink);border-color:var(--ink-3);}
.what.on{background:var(--ink);border-color:var(--ink);color:var(--bg);}
.what:active{transform:scale(.9);transition-duration:90ms;}
.section-sub{animation:what-in var(--t-base) var(--out) both;}
@keyframes what-in{from{opacity:0;transform:translateY(-3px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion: reduce){.section-sub{animation:none;}}

/* A day on Home carries whatever the season plan says, and some of those
   entries are a paragraph. Three lines is a glance; the rest is one tap
   away on the day itself, which is where a coach goes to read it anyway. */
.call-focus{
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;
  overflow:hidden;
}
.call-note{
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;
  overflow:hidden;
}


/* ============================================================
   17. THE EDITORIAL LAYER — the prototype's real idea.

   Eóin pointed at his own Súil prototype and said it is still the
   best version. Comparing them, the difference was never the type
   or the colour: it is that the prototype does not put things in
   boxes. A section is a label on a hairline with its number on the
   right; a day is a column under a rule with what it IS set large;
   the fixture is a line of type, not a card.

   Cards say "here is a component". Hairlines and type say "here is
   the information". That is the whole gap, and it costs nothing to
   run — no borders, no shadows, no hover lifts.
   ============================================================ */

/* The label on a rule: a name on the left, its number on the right, one
   hairline under both. This is the section header for the whole app. */
.lab{
  display:flex;justify-content:space-between;align-items:baseline;gap:var(--s-4);
  font-size:var(--fs-sm);font-weight:500;color:var(--ink-2);margin:0;
}
.lab.rule{padding-bottom:8px;border-bottom:1px solid var(--line);margin-bottom:var(--s-4);}
.lab .n{font-family:var(--display);font-weight:600;font-size:var(--fs-lg);color:var(--ink);
  font-variant-numeric:tabular-nums;letter-spacing:0;}
.lab.gap-top,.gap-top{margin-top:var(--s-6);}
:root[data-sun="on"] .lab.rule{border-bottom-width:2px;border-bottom-color:var(--line-2);}

/* A quiet button: a link that happens to be a control. Used where a card
   used to be a whole clickable box. */
.btn-quiet{background:none;color:var(--ink-2);padding:4px 0;font-weight:500;}
.btn-quiet:hover{color:var(--ink);}

/* THE FIXTURE. The one thing the week points at. */
.fixture{
  display:flex;align-items:flex-start;gap:var(--s-4);
  padding:0 0 var(--s-6);
}
.fixture-crest{flex:none;width:56px;height:56px;display:grid;place-items:center;}
.fixture-crest svg,.fixture-crest img{width:56px;height:56px;}
.fixture-who{flex:1;min-width:0;}
.fixture-line{
  font-family:var(--display);font-weight:700;font-size:clamp(22px,2.4vw,30px);
  line-height:1.08;letter-spacing:-.01em;color:var(--ink);
}
.fixture-line .v{color:var(--ink-3);font-weight:600;}
.fixture .muted{font-size:var(--fs-base);color:var(--ink-2);margin-top:3px;}
.fixture-when{flex:none;text-align:right;display:flex;flex-direction:column;align-items:flex-end;gap:var(--s-3);}
.ko{
  font-family:var(--display);font-weight:800;font-size:clamp(28px,3.4vw,44px);
  line-height:1;letter-spacing:-.01em;color:var(--ink);font-variant-numeric:tabular-nums;
}
.fixture.empty .fixture-line{font-size:clamp(20px,2vw,24px);color:var(--ink-2);}

/* FIVE DAYS, five columns, one rule across the top of each. No card. */
.days{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:var(--s-3);}
.day{
  position:relative;text-align:left;width:100%;min-height:112px;
  padding:var(--s-3) var(--s-3) var(--s-4) 0;
  border-top:1px solid var(--line-2);background:none;
  transition:background var(--t-fast) var(--ease);
}
.day:hover{background:var(--surface-2);}
.day .w{
  font-size:var(--fs-sm);color:var(--ink-2);font-weight:500;
  display:flex;align-items:center;gap:4px;
}
.day .dot{width:6px;height:6px;border-radius:50%;background:var(--accent);flex:none;}
.day .d{
  font-family:var(--display);font-weight:700;font-size:var(--fs-xl);
  line-height:1.06;margin-top:2px;color:var(--ink);letter-spacing:-.01em;
}
.day.is-game .d{color:var(--accent-deep);}
.day.is-today{border-top-color:var(--accent);border-top-width:2px;}
.day p{
  font-size:var(--fs-sm);line-height:1.45;color:var(--ink-2);margin:4px 0 0;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
@media(max-width:1000px){ .days{grid-template-columns:repeat(3,minmax(0,1fr));} }
@media(max-width:640px){ .days{grid-template-columns:repeat(2,minmax(0,1fr));} }

/* Two columns of prose under their own rules. */
.grid2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s-6);}
@media(max-width:860px){ .grid2{grid-template-columns:1fr;gap:var(--s-5);} }
.lead{font-size:var(--fs-md);line-height:1.5;color:var(--ink-2);margin:0;max-width:52ch;}
.lead.warn{color:var(--amber);font-weight:var(--w-emph);margin-top:var(--s-3);font-size:var(--fs-base);}
.row-acts{display:flex;gap:var(--s-3);align-items:center;flex-wrap:wrap;margin-top:var(--s-4);}
.faces-row{display:flex;align-items:center;}

/* Home's headline is the date, and it is the biggest thing in the app. */
.section.home h1{
  font-family:var(--display);font-weight:800;
  font-size:clamp(34px,4.6vw,64px);line-height:1.02;letter-spacing:-.015em;
}
.section.home h1 .muted{color:var(--ink-3);font-weight:700;}

/* ---------- 17b. the rail, quieted ----------
   The prototype's rail is sentence case at reading size, and its current
   item is a thin bar and darker ink rather than a white slab. Condensed
   caps were the Léargas signature and they are loud next to this: six
   words a coach knows by shape do not need to shout to be found. Eóin's
   call, 7 Sep 2026, pointing at his own prototype: "this is still the
   best version."
   Contrast on the rail, computed: resting 5.3:1, current 12.8:1. */
nav .nav-btn,
nav .nav-sub-btn{
  font-family:var(--body);text-transform:none;letter-spacing:-.005em;
  font-weight:500;color:var(--on-rail-2);
}
@media(min-width:861px){
  nav .nav-btn{font-size:var(--fs-md);min-height:40px;padding:8px 8px;}
  nav .nav-sub-btn{font-size:var(--fs-base);min-height:36px;}
  nav .nav-btn svg{width:18px;height:18px;}
  nav .nav-btn.active,
  .nav-folder.active>.nav-btn.active{
    background:none;box-shadow:none;color:var(--on-rail);font-weight:var(--w-emph);
  }
  nav .nav-btn.active svg,
  .nav-folder.active>.nav-btn.active svg{color:var(--rail-accent);}
  nav .nav-btn.active::after,
  .nav-folder.active>.nav-btn.active::after{display:none;}
  nav .nav-btn{position:relative;}
}
.brand-title{font-size:var(--fs-lg);}

/* Needs you, as rows under a rule. */
.needs{margin-top:var(--s-6);}
.needs-row{
  display:flex;align-items:center;gap:var(--s-3);
  padding:12px 0;border-bottom:1px solid var(--line);cursor:pointer;
  transition:padding-left var(--t-fast) var(--ease);
}
.needs-row:hover{padding-left:4px;}


/* ============================================================
   18. THE BOARD IS AN OBJECT.

   A tactics board where the players teleport is a diagram. One
   where they travel, lift under the finger and settle with weight
   is a board. The motion is carried by an inner <g> inside every
   token so the drag code keeps owning the outer transform, and by
   a spring rather than an ease, because a face landing on a spot
   should overshoot a little and settle — that is what tells a
   coach it arrived rather than appeared.
   ============================================================ */
.lu-move{transform-box:fill-box;transform-origin:center;will-change:transform;}

/* the ring is the identity, so the ring is what reacts */
.lu-ring{transition:stroke-width var(--t-fast) var(--ease);}
@media (hover:hover) and (pointer:fine){
  .lu-tok:hover .lu-ring{stroke-width:4.5;}
}
.lu-shadow{transition:opacity var(--t-fast) var(--ease),transform var(--t-fast) var(--out);}

/* in the air */
.lu-tok.lu-lift{cursor:grabbing;}
.lu-tok.lu-lift .lu-move{transform:scale(1.1);transition:transform var(--t-fast) var(--out);}
.lu-tok.lu-lift .lu-ring{stroke-width:4.5;}
.lu-tok.lu-lift .lu-shadow{opacity:.34;transform:translateY(9px) scale(1.02);}

/* everything the carried face is not */
#luSvg.lu-carrying .lu-tok:not(.lu-lift) .lu-move{opacity:.72;transition:opacity var(--t-fast) var(--ease);}

/* where it will land */
.lu-near .lu-ring-near{opacity:.55;animation:lu-pulse 1.1s var(--ease) infinite;}
.lu-tok.lu-near .lu-ring{stroke-width:5;}
@keyframes lu-pulse{
  0%,100%{transform:scale(1);opacity:.5}
  50%{transform:scale(1.08);opacity:.24}
}
.lu-ring-near{transform-box:fill-box;transform-origin:center;transition:opacity var(--t-fast) var(--ease);}

@media (prefers-reduced-motion: reduce){
  .lu-move,.lu-shadow,.lu-ring{transition:none !important;}
  .lu-near .lu-ring-near{animation:none;}
}


/* ============================================================
   19. ⌘K — the field that replaces the menu.
   ============================================================ */
.rail-find{
  display:flex;align-items:center;gap:var(--s-2);
  margin:0 var(--s-3) var(--s-3);padding:0 8px;min-height:38px;flex:none;
  border-radius:var(--r-md);background:var(--rail-2);
  color:var(--on-rail-2);font-size:var(--fs-base);font-weight:500;
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease);
}
.rail-find span{flex:1;text-align:left;}
.rail-find kbd{
  font-family:var(--body);font-size:var(--fs-xs);font-weight:var(--w-emph);
  color:var(--on-rail-2);opacity:.8;letter-spacing:.02em;
}
.rail-find:hover{background:var(--rail-on);color:var(--rail-on-ink);}
.rail-find:hover kbd{color:var(--rail-on-ink);}

#cmdRoot{display:none;}
#cmdRoot.open{display:block;}
.cmd-scrim{
  position:fixed;inset:0;z-index:9500;background:rgba(18,20,18,.44);
  animation:cmd-scrim var(--t-fast) var(--ease) both;
}
@keyframes cmd-scrim{from{opacity:0}to{opacity:1}}
.cmd{
  position:fixed;z-index:9501;left:50%;top:14vh;transform:translateX(-50%);
  width:min(560px, calc(100vw - 32px));
  border-radius:var(--r-lg);overflow:hidden;isolation:isolate;
  background:color-mix(in srgb, var(--surface) 92%, transparent);
  -webkit-backdrop-filter:blur(26px) saturate(170%);
          backdrop-filter:blur(26px) saturate(170%);
  box-shadow:var(--sh-lift-2), inset 0 0 0 1px var(--line);
  animation:cmd-in 260ms var(--out) both;
}
@keyframes cmd-in{
  from{opacity:0;transform:translateX(-50%) translateY(-10px) scale(.98)}
  to{opacity:1;transform:translateX(-50%) translateY(0) scale(1)}
}
.cmd-field{
  display:flex;align-items:center;gap:var(--s-3);
  padding:0 var(--s-4);min-height:58px;border-bottom:1px solid var(--line);
}
.cmd-field svg{color:var(--ink-3);flex:none;}
.cmd-field input{
  flex:1;min-width:0;border:0;background:none;outline:none;
  font-size:var(--fs-lg);font-weight:500;color:var(--ink);
}
.cmd-field input::placeholder{color:var(--ink-3);font-weight:400;}
.cmd-field kbd{
  font-family:var(--body);font-size:var(--fs-xs);color:var(--ink-3);
  border:1px solid var(--line-2);border-radius:var(--r-xs);padding:2px 4px;
}
.cmd-list{max-height:min(52vh, 420px);overflow-y:auto;padding:var(--s-2);}
.cmd-row{
  display:flex;align-items:center;gap:var(--s-3);width:100%;
  min-height:44px;padding:0 8px;border-radius:var(--r-md);text-align:left;
  color:var(--ink);font-size:var(--fs-md);
}
.cmd-row.on{background:var(--accent-soft);}
.cmd-row.on .cmd-label{font-weight:var(--w-emph);}
.cmd-ico{width:28px;display:flex;align-items:center;justify-content:center;flex:none;color:var(--ink-3);}
.cmd-ico .lu-ava{width:26px;height:26px;font-size:9px;}
.cmd-dot{width:16px;height:16px;border-radius:50%;background:var(--sw);}
.cmd-form{
  font-family:var(--display);font-weight:700;font-size:var(--fs-sm);
  color:var(--ink-2);letter-spacing:-.02em;
}
.cmd-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.cmd-hint{font-size:var(--fs-sm);color:var(--ink-3);flex:none;}
.cmd-none{padding:16px 12px;color:var(--ink-3);font-size:var(--fs-base);}
:root[data-sun="on"] .cmd{
  background:var(--surface);-webkit-backdrop-filter:none;backdrop-filter:none;
  box-shadow:none;border:2px solid var(--line-2);
}
@media (prefers-reduced-motion: reduce){
  .cmd,.cmd-scrim{animation:none;}
}


/* ============================================================
   20. THE SQUAD IS A WALL OF FACES.

   The signature of the product, given the room it deserves: one
   photo per player at 76px, his surname under it, his number and
   position under that. The keeper wears gold, an unavailable
   player is desaturated rather than badged, and the ring thickens
   under the cursor — the same ring the mark's iris is drawn as.
   ============================================================ */
.squad-wall{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(104px,1fr));
  gap:var(--s-5) var(--s-3);margin-top:var(--s-5);
}
.pl{
  display:flex;flex-direction:column;align-items:center;gap:8px;
  padding:0;background:none;text-align:center;min-width:0;
}
.pl-face{
  width:76px;height:76px;border-radius:50%;overflow:hidden;flex:none;
  background:var(--surface-2);border:3px solid var(--accent);
  display:grid;place-items:center;box-sizing:border-box;
  transition:border-width var(--t-fast) var(--ease),transform 250ms var(--spring),
             filter 200ms var(--ease);
}
.pl-face.gk{border-color:var(--gold-accent);}
.pl-face.out{filter:grayscale(1);border-color:var(--line-2);}
.pl-face img{width:100%;height:100%;object-fit:cover;object-position:50% 12%;display:block;}
.pl-ini{font-family:var(--display);font-weight:700;font-size:26px;color:var(--ink-3);}
.pl-name{
  font-size:var(--fs-base);font-weight:var(--w-emph);color:var(--ink);
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.pl-meta{font-size:var(--fs-sm);color:var(--ink-3);display:flex;gap:4px;align-items:baseline;}
.pl-meta b{
  font-family:var(--display);font-weight:700;color:var(--ink-2);
  font-variant-numeric:tabular-nums;font-size:var(--fs-base);
}
.pl-meta i{font-style:normal;color:var(--amber);}
@media (hover:hover) and (pointer:fine){
  .pl:hover .pl-face{border-width:5px;transform:translateY(-3px);}
  .pl:hover .pl-face.out{filter:none;}
}
.pl:active .pl-face{transform:scale(.95);transition-duration:90ms;}

/* the filter row, with counts */
.squad-filter{margin:0 0 var(--s-2);}
.pill-n{
  margin-left:4px;font-variant-numeric:tabular-nums;opacity:.55;
  font-size:var(--fs-xs);
}
.pill:disabled{opacity:.3;cursor:default;}

/* the command bar's shape labels sit on one line */
.cmd-ico{width:36px;}
.cmd-form{white-space:nowrap;font-size:var(--fs-xs);}

/* ---------- 20b. the other squads, when asked for ----------
   Three boxes stacked under the name were the heaviest thing in a rail that
   is otherwise six quiet words. The squad a coach is in is already written
   under the wordmark; the others are behind a chevron. */
.team-switch{margin:0 var(--s-3) var(--s-3);flex:none;}
.team-cur{
  display:flex;align-items:center;gap:var(--s-2);width:100%;
  min-height:38px;padding:0 8px;border-radius:var(--r-md);
  background:var(--rail-2);color:var(--on-rail);
  font-size:var(--fs-base);font-weight:var(--w-emph);
  transition:background var(--t-fast) var(--ease);
}
.team-cur span{flex:1;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.team-cur img{width:20px;height:20px;object-fit:contain;flex:none;}
.team-chev{color:var(--on-rail-2);transition:transform var(--t-base) var(--out);}
.team-switch.open .team-chev{transform:rotate(90deg);}
.team-others{
  display:grid;grid-template-rows:0fr;
  transition:grid-template-rows var(--t-base) var(--out);
}
.team-switch.open .team-others{grid-template-rows:1fr;}
.team-others>div{overflow:hidden;}
.team-other{
  display:flex;align-items:center;gap:var(--s-2);
  min-height:36px;padding:0 8px;margin-top:2px;border-radius:var(--r-md);
  color:var(--on-rail-2);font-size:var(--fs-base);text-decoration:none;
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease);
}
.team-other img{width:18px;height:18px;object-fit:contain;flex:none;}
.team-other:hover{background:var(--rail-2);color:var(--on-rail);}

.fixture-who{text-align:left;}
.fixture-when .btn-quiet{padding:0;}


/* ============================================================
   21. THE SCREEN ARRIVES IN ORDER.

   One reveal per screen was the rule, and it still is — this is
   one reveal, read top to bottom, 40ms between blocks and done in
   under half a second. It is the same `.rv` idea the prototype
   uses and it is what stops a screen from simply BEING there.
   Five steps and then everything else lands together, so a long
   page never parades.
   ============================================================ */
.section.enter{animation:none;}
.section.enter>*{animation:rv var(--t-slow) var(--out) both;}
.section.enter.rev>*{animation-name:rv-back;}
.section.enter>*:nth-child(1){animation-delay:0ms;}
.section.enter>*:nth-child(2){animation-delay:45ms;}
.section.enter>*:nth-child(3){animation-delay:90ms;}
.section.enter>*:nth-child(4){animation-delay:135ms;}
.section.enter>*:nth-child(n+5){animation-delay:175ms;}
@keyframes rv{
  from{opacity:0;transform:translate3d(14px, 6px, 0)}
  to{opacity:1;transform:none}
}
/* Coming back arrives from the other side. */
@keyframes rv-back{
  from{opacity:0;transform:translate3d(-14px, 6px, 0)}
  to{opacity:1;transform:none}
}
:root[data-sun="on"] .section.enter>*{animation:none;}
@media (prefers-reduced-motion: reduce){
  .section.enter>*{animation:none;}
}


/* ============================================================
   22. HIS OWN WORDS.

   The list a coach is offered after Súil reads his game model.
   It is a proposal, so it reads like one: the word, how many
   times he said it, and the sentence he said it in — enough to
   recognise his own writing and tick without opening the file.
   ============================================================ */
.mw{max-width:none;}
.mw-group{margin-bottom:var(--s-5);}
.mw-group .lab{margin-bottom:var(--s-2);}
.mw-list{display:flex;flex-direction:column;}
.mw-row{
  display:grid;grid-template-columns:20px minmax(0,auto) auto minmax(0,1fr);
  gap:var(--s-3);align-items:baseline;
  padding:8px 8px;border-radius:var(--r-sm);cursor:pointer;
  border-bottom:1px solid var(--line);
  transition:background var(--t-fast) var(--ease);
}
.mw-row:hover{background:var(--surface-2);}
.mw-row.on{background:var(--accent-soft);}
.mw-row input{margin:0;accent-color:var(--accent);width:16px;height:16px;}
.mw-word{font-weight:var(--w-emph);color:var(--ink);font-size:var(--fs-md);white-space:nowrap;}
.mw-count{
  font-family:var(--display);font-weight:700;color:var(--ink-3);
  font-variant-numeric:tabular-nums;font-size:var(--fs-base);
}
.mw-eg{
  font-size:var(--fs-sm);color:var(--ink-3);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
@media(max-width:720px){
  .mw-row{grid-template-columns:20px 1fr auto;}
  .mw-eg{display:none;}
}

/* the vocabulary, once he has chosen it */
.mw-chips{display:flex;flex-wrap:wrap;gap:var(--s-2);}
.mw-chip{
  display:inline-flex;align-items:center;gap:8px;
  padding:4px 8px 4px 12px;border-radius:var(--r-capsule);
  background:var(--accent-soft);color:var(--accent-deep);
  font-size:var(--fs-base);font-weight:var(--w-emph);
}
.mw-chip i{font-style:normal;font-weight:400;opacity:.7;font-size:var(--fs-sm);}
.mw-chip button{
  width:20px;height:20px;border-radius:50%;flex:none;
  color:var(--accent-deep);opacity:.55;font-size:15px;line-height:1;
  transition:opacity var(--t-fast) var(--ease),background var(--t-fast) var(--ease);
}
.mw-chip button:hover{opacity:1;background:rgba(var(--accent-rgb),.16);}


/* ============================================================
   23. THE TOUCHLINE.

   BRIEF §6 and SUIL_README §9 v1.2: 44pt floor, 52 on gameday,
   64 for the whistle; kick-off, half-time and full-time are held
   for 600ms, not tapped. The clock button used to be a 34px
   `btn-sm` that cycled state on one tap and, one second after it
   said "Full-time", said "Reset clock" in the same pixels.
   ============================================================ */
.gd-clock-acts{display:flex;align-items:center;gap:var(--s-2);flex-wrap:wrap;}
.gd-min{
  min-width:52px;height:52px;border-radius:var(--r-md);
  background:var(--surface-2);color:var(--ink-2);
  font-family:var(--display);font-weight:700;font-size:var(--fs-lg);
  font-variant-numeric:tabular-nums;
  transition:background var(--t-fast) var(--ease),transform 250ms var(--spring);
}
.gd-min:hover{background:var(--surface-3);color:var(--ink);}
.gd-min:active{transform:scale(.95);transition-duration:90ms;}
.gd-pause{
  min-height:52px;padding:0 var(--s-4);border-radius:var(--r-md);
  background:var(--surface-2);color:var(--ink-2);
  font-size:var(--fs-md);font-weight:var(--w-emph);
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease);
}
.gd-pause.on{background:var(--amber-soft);color:var(--amber);}

/* the whistle: 64 tall, held, and it fills while you hold it */
.gd-whistle{
  position:relative;isolation:isolate;overflow:hidden;
  min-height:64px;min-width:150px;padding:0 var(--s-5);
  border-radius:var(--r-md);background:var(--accent);color:var(--on-accent);
  display:inline-flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;
  font-family:var(--display);font-weight:700;font-size:var(--fs-xl);
  letter-spacing:-.01em;line-height:1;
  touch-action:none;-webkit-user-select:none;user-select:none;
}
.gd-whistle .lbl,.gd-whistle .hint{position:relative;z-index:1;}
.gd-whistle .hint{
  font-family:var(--body);font-size:var(--fs-sm);font-weight:500;
  letter-spacing:0;text-transform:none;color:var(--on-accent);
}
.gd-whistle .fill{
  position:absolute;left:0;top:0;bottom:0;width:100%;z-index:0;
  transform:scaleX(0);transform-origin:left center;
  background:rgba(255,255,255,.28);
}
.gd-whistle.holding .fill{transform:scaleX(1);transition:transform 600ms linear;}
.gd-whistle:active{filter:brightness(1.06);}
.gd-whistle.done{
  min-height:64px;padding:0 var(--s-5);border-radius:var(--r-md);
  display:inline-flex;align-items:center;
  background:var(--surface-2);color:var(--ink-2);
  font-family:var(--display);font-weight:700;font-size:var(--fs-xl);
}
:root[data-sun="on"] .gd-whistle{box-shadow:inset 0 0 0 2px var(--accent-deep);}
@media (prefers-reduced-motion: reduce){
  .gd-whistle.holding .fill{transition:none;transform:scaleX(1);opacity:.4;}
}

/* the clock reads as stopped when it is stopped */
.gd-clock-num.held{opacity:.62;}
.gd-clock-num.held::after{
  content:"";display:inline-block;width:9px;height:14px;margin-left:8px;
  border-left:3px solid currentColor;border-right:3px solid currentColor;
  vertical-align:-1px;
}
.icon-btn.armed{background:var(--red-soft);color:var(--red);}

/* gameday's own floor: nothing a coach touches during a match is under 52 */
.gd-chips .gd-chip{min-height:52px;}
.gd-score .btn{min-height:44px;}


/* ============================================================
   24. ONE LANGUAGE, EVERYWHERE.

   Eóin, 8 Sep 2026: "give the website a consistent feeling —
   elite, premium, slick, modern, unique. What I am using here is
   high end."

   The editorial layer landed on Home, Squad and the board while
   nine other screens were still wearing August: bordered cards
   with shadows, tracked uppercase eyebrows, a serif heading, ad
   hoc button rows. This section is the rest of the app catching
   up. It is deliberately a small number of rules applied widely
   rather than per-screen styling — consistency is a system, not
   a coat of paint.
   ============================================================ */

/* THE CARD, quieted. A card should be a surface, not a component with
   a frame. One hairline, no shadow, no hover lift; the shadow is spent
   on the two chrome surfaces that float, and nowhere else. */
.card{box-shadow:none;border-color:var(--line);}
.card.hoverable:hover{box-shadow:none;transform:none;background:var(--surface-2);}
.card.pad{padding:var(--s-5);}

/* THE CARD TITLE becomes a rule, like every other section head. */
.card-title{
  font-size:var(--fs-sm);font-weight:500;color:var(--ink-2);
  letter-spacing:0;text-transform:none;
  padding-bottom:8px;margin-bottom:var(--s-4);
  border-bottom:1px solid var(--line);
}
.card-title svg{color:var(--ink-3);}

/* THE EYEBROW stops shouting. Tracked caps at 11px were the loudest
   thing on eleven screens and said the least. */
.u-label,.glance-label,.eyebrow{
  font-size:var(--fs-sm);font-weight:500;letter-spacing:0;
  text-transform:none;color:var(--ink-2);
}
.u-label{border-bottom:0;padding-bottom:0;}

/* NO SERIF. The one face that was never in the brief. */
.section h1,.brand-title,h1,h2,h3{font-family:var(--display);}
.card-title,.u-label{font-family:var(--body);}

/* NUMBERS ARE THE DISPLAY FACE and they line up. Every figure a coach
   compares — minutes, scores, counts, ratings — is tabular. */
.glance-v,.ses-tl-seg span,.tag,.pill-n,.n,.call-num,.metric .v{
  font-variant-numeric:tabular-nums;
}
.glance-v{font-family:var(--display);font-weight:700;letter-spacing:-.01em;}

/* CONTROLS. One height, one radius, one press. */
.pill{
  border-radius:var(--r-capsule);
  font-size:var(--fs-base);font-weight:500;
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease),
             transform 250ms var(--spring);
}
.pill.active{font-weight:var(--w-emph);}
.pill:active{transform:scale(.97);transition-duration:90ms;}
.seg{border-radius:var(--r-capsule);overflow:hidden;}
input[type=text],input[type=url],input[type=date],input[type=number],
input[type=email],select,textarea,.field{
  border-radius:var(--r-sm);border:1px solid var(--line-2);
  background:var(--surface);color:var(--ink);
  transition:border-color var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease);
}
input:focus-visible,select:focus-visible,textarea:focus-visible,.field:focus-visible{
  outline:none;border-color:var(--accent);box-shadow:var(--ring);
}

/* THE NEXT SESSION — the Sessions door's own object. */
.next-session{
  display:flex;flex-direction:column;align-items:flex-start;gap:4px;
  width:100%;text-align:left;padding:var(--s-4) 0;
  border-bottom:1px solid var(--line);background:none;
  transition:padding-left var(--t-base) var(--out);
}
.next-session:hover{padding-left:8px;}
.ns-when{font-size:var(--fs-sm);color:var(--ink-2);}
.ns-when b{
  font-family:var(--display);font-weight:700;font-size:var(--fs-xl);
  color:var(--ink);letter-spacing:-.01em;margin-right:4px;
}
.ns-what{font-size:var(--fs-md);color:var(--ink);max-width:64ch;}
.ns-go{font-size:var(--fs-base);color:var(--accent-deep);font-weight:var(--w-emph);}




/* ============================================================
   25. THE EYE.

   Eóin, 8 Sep 2026: "add the Súil eye logo top right, and add it
   blinking to any loading screen."

   It sits where a mark goes, and it earns the corner by doing a
   job: it blinks while the hub is actually working — saving,
   reading a roster off an athletics site, drawing a picture — and
   rests the rest of the time. Every spinner in the app is now this
   same mark at the size the control can afford, so "thinking"
   looks like one thing everywhere instead of a loader here and a
   dot there. It blinks; it never spins, and it never blinks
   forever: the work ending stops it.
   ============================================================ */
.suil-eye{display:block;color:var(--ink-3);}
.suil-eye svg{display:block;width:100%;height:auto;}
.suil-eye .pupil{fill:var(--accent);}
.suil-eye .lid,.suil-eye .iris,.suil-eye .stub{
  transform-box:fill-box;transform-origin:center;
}

/* THE MARK, TOP RIGHT — and actually present.

   It was here already and Eóin could not find it, which is the whole review:
   30px at 50% opacity in the tertiary grey, and `display:none` below 860px,
   so on a laptop window it was a smudge and on a narrow one it did not exist
   at all. That is a watermark. A watermark is what you put on something when
   you are not sure it is yours.

   Now: 34px, full strength, in the ink the rest of the chrome is drawn in,
   and it appears at every width — on a phone it moves into the top bar
   rather than vanishing, because the top right of the window is the top
   right of the window whatever the screen is.

   It still does the one thing that earns a mark its place: it blinks while
   the hub is genuinely working and rests otherwise. A logo that reacts is a
   status light. A logo that just sits there is a sticker. */
#suilEye{
  position:absolute;top:var(--s-5);right:var(--s-5);z-index:28;
  width:34px;pointer-events:none;
  color:var(--ink-2);opacity:.9;
  transition:opacity var(--t-base) var(--ease),color var(--t-base) var(--ease);
}
#suilEye .pupil{fill:var(--accent);}
#suilEye.working{opacity:1;color:var(--ink);}
#main{position:relative;}
/* On a phone it stays top-right of the PAGE rather than moving into the top
   bar — the bar's right end already holds the two theme controls, and the
   first attempt at this put the mark straight on top of the sun button. The
   corner below the bar is the same corner, and it is empty. */
@media(max-width:860px){
  /* The top bar is a sibling INSIDE #main, 53px tall and painted at z-30, so
     an absolutely positioned mark at top:16 sits behind it. It goes below the
     bar — the same corner of the same page, just under the chrome rather than
     inside it. */
  #suilEye{ width:26px; top:calc(53px + var(--s-3)); right:var(--s-4); }
}

/* working: the lid closes, the iris goes with it, twice a second and a half */
.suil-eye.working .lid{animation:eye-blink 1500ms var(--ease) infinite;}
.suil-eye.working .iris,.suil-eye.working .stub{animation:eye-iris 1500ms var(--ease) infinite;}
@keyframes eye-blink{0%,58%,100%{transform:scaleY(1)}66%{transform:scaleY(.06)}74%{transform:scaleY(1)}}
@keyframes eye-iris{0%,58%,100%{opacity:1}64%,72%{opacity:0}}

/* inline, inside a button that is waiting */
.suil-eye.inline{
  display:inline-block;vertical-align:-3px;color:currentColor;flex:none;
}
.suil-eye.inline .pupil{fill:currentColor;}

/* the front door's own wait */
.door-eye{display:flex;justify-content:center;margin-top:var(--s-6);}
.door-eye .suil-eye{width:58px;color:var(--ink-2);}

@media (prefers-reduced-motion: reduce){
  .suil-eye.working .lid,.suil-eye.working .iris,.suil-eye.working .stub{animation:none;}
  #suilEye.working{opacity:1;}
}
:root[data-sun="on"] #suilEye{opacity:.75;}


/* ============================================================
   26. GAMEDAY HAS A DAY IN IT.

   Eóin, 8 Sep 2026: "make the Gameday screen have more
   character, it is a little too stale."

   It was a two-column desk page that happened to be about a
   match: a thin card whose score was smaller than the button
   beside it, four generic doors, and the eleven as 12px chips
   with 10.5px numbers — on the one screen where a coach is NOT
   looking at the screen. The brief has said what this should be
   since day one and nobody had built it: score and live clock at
   --fs-10, the strip pinned so the two numbers he checks forty
   times an hour never scroll away, and faces.
   ============================================================ */
.gd-strip{
  position:sticky;top:0;z-index:24;
  margin:0 calc(var(--s-5) * -1) var(--s-5);
  padding:var(--s-5) var(--s-5) var(--s-4);
  background:color-mix(in srgb, var(--surface) 82%, transparent);
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));
          backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));
  border-bottom:1px solid var(--line);
}
.gd-strip.live{border-bottom-color:var(--accent);}
.gd-strip-top{
  display:grid;grid-template-columns:1fr auto 1fr;
  align-items:center;gap:var(--s-4);
}
.gd-side{display:flex;align-items:center;gap:var(--s-3);min-width:0;}
.gd-side.theirs{justify-content:flex-end;}
.gd-crest{width:30px;height:30px;flex:none;display:grid;place-items:center;}
.gd-crest.them{
  border-radius:50%;background:var(--surface-2);color:var(--ink-3);
  font-family:var(--display);font-weight:700;font-size:var(--fs-sm);
}
.gd-name{
  font-family:var(--display);font-weight:700;
  font-size:clamp(15px,1.8vw,24px);line-height:1.05;letter-spacing:-.01em;
  color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* the score IS the screen */
.gd-score-nums{display:flex;align-items:baseline;gap:var(--s-3);}
.gd-goal{
  font-family:var(--display);font-weight:800;
  font-size:clamp(52px,9vw,96px);line-height:.9;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;color:var(--ink);
  min-width:52px;padding:0 4px;border-radius:var(--r-md);
  transition:background var(--t-fast) var(--ease),transform 250ms var(--spring);
}
.gd-goal:hover{background:var(--accent-soft);color:var(--accent-deep);}
.gd-goal:active{transform:scale(.94);transition-duration:90ms;}
.gd-dash{
  font-family:var(--display);font-weight:600;color:var(--ink-3);
  font-size:clamp(30px,5vw,56px);line-height:1;
}

.gd-strip-bottom{
  display:flex;align-items:center;justify-content:space-between;
  gap:var(--s-4);flex-wrap:wrap;margin-top:var(--s-4);
}
.gd-period{display:flex;align-items:baseline;gap:var(--s-3);min-width:0;}
.gd-clock-num{
  font-family:var(--display);font-weight:800;
  font-size:clamp(30px,4vw,52px);line-height:1;letter-spacing:-.01em;
  font-variant-numeric:tabular-nums;color:var(--ink-2);
}
.gd-clock-num.live{color:var(--accent-deep);}
.gd-period-name{font-size:var(--fs-base);color:var(--ink-3);}

/* THE ELEVEN, AS FACES. Two taps still makes the sub. */
.gdf-wall{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(84px,1fr));
  gap:var(--s-4) var(--s-2);margin-top:var(--s-4);
}
.gdf{
  display:flex;flex-direction:column;align-items:center;gap:4px;
  padding:0;background:none;min-height:52px;position:relative;
}
.gdf-face{
  width:62px;height:62px;border-radius:50%;overflow:hidden;flex:none;
  background:var(--surface-2);border:3px solid var(--accent);
  display:grid;place-items:center;box-sizing:border-box;
  transition:border-width var(--t-fast) var(--ease),transform 250ms var(--spring);
}
.gdf.gk .gdf-face{border-color:var(--gold-accent);}
.gdf-face img{width:100%;height:100%;object-fit:cover;object-position:50% 12%;display:block;}
.gdf-ini{font-family:var(--display);font-weight:700;font-size:21px;color:var(--ink-3);}
.gdf-num{
  position:absolute;top:44px;left:50%;transform:translateX(-50%);
  min-width:22px;height:22px;padding:0 4px;border-radius:var(--r-capsule);
  background:var(--accent);color:var(--on-accent);
  font-family:var(--display);font-weight:700;font-size:13px;line-height:22px;
  font-variant-numeric:tabular-nums;text-align:center;
  box-shadow:0 0 0 2px var(--surface);
}
.gdf.gk .gdf-num{background:var(--gold-accent);color:#231F0A;}
.gdf-name{
  margin-top:8px;font-size:var(--fs-sm);font-weight:var(--w-emph);color:var(--ink);
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.gdf.on .gdf-face{border-width:6px;transform:translateY(-3px);}
.gdf-wall.bench .gdf-face{width:52px;height:52px;}
.gdf-wall.bench .gdf-num{top:36px;}
.gdf-wall.bench .gdf-ini{font-size:17px;}
@media (hover:hover) and (pointer:fine){ .gdf:hover .gdf-face{border-width:5px;} }

/* THE MATCH, as a timeline: the minute in the display face, the event beside it */
.gd-quick{display:flex;gap:var(--s-2);margin:var(--s-4) 0;}
.gd-quick input{flex:1;min-width:0;min-height:44px;padding:0 var(--s-3);}
.gd-log .gd-ev{
  display:grid;grid-template-columns:46px 1fr auto;gap:var(--s-3);
  align-items:baseline;padding:12px 0;border-bottom:1px solid var(--line);
}
.gd-log .gd-ev-min{
  font-family:var(--display);font-weight:700;font-size:var(--fs-lg);
  font-variant-numeric:tabular-nums;color:var(--ink-3);text-align:right;
}
.gd-log .gd-ev.goal .gd-ev-min{color:var(--accent-deep);}
.gd-people,.gd-logwrap,.gd-notes{min-width:0;}
.gd-notes textarea{width:100%;min-height:150px;}

@media(max-width:860px){
  .gd-strip{margin-left:calc(var(--s-4) * -1);margin-right:calc(var(--s-4) * -1);padding:var(--s-4);}
  .gd-strip-top{grid-template-columns:1fr;justify-items:center;gap:var(--s-2);}
  .gd-side.theirs{justify-content:center;}
}
:root[data-sun="on"] .gd-strip{
  background:var(--surface);-webkit-backdrop-filter:none;backdrop-filter:none;
  border-bottom:2px solid var(--line-2);
}


/* ---------- 26b. the opposition's shirt ----------
   A coach says "the team in the red and black stripes", never "the team in
   #B23B27". So the control is a shirt he looks at: the pattern chips ARE the
   pattern, drawn with his chosen colours, and the preview is the token he is
   about to stamp. */
.kit-bar{
  display:flex;align-items:center;gap:var(--s-3);flex-wrap:wrap;
  padding:var(--s-3) 0;margin-bottom:var(--s-3);
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
}
.kit-bar select{min-height:34px;padding:0 var(--s-2);max-width:220px;}
.kit-shirt{width:30px;height:30px;flex:none;}
.kit-shirt svg{width:100%;height:100%;display:block;}
.kit-pats,.kit-cols{display:flex;gap:4px;align-items:center;}
.kit-pat{
  width:30px;height:30px;padding:2px;border-radius:50%;flex:none;
  transition:transform 250ms var(--spring),box-shadow var(--t-fast) var(--ease);
}
.kit-pat svg{width:100%;height:100%;display:block;border-radius:50%;}
.kit-pat:hover{transform:scale(1.1);}
.kit-pat.on{box-shadow:0 0 0 2px var(--accent);}
.kit-col{
  width:22px;height:22px;padding:4px;border-radius:50%;flex:none;
  background:var(--c);background-clip:content-box;
  box-shadow:inset 0 0 0 1px var(--line-2);
  transition:transform 250ms var(--spring),box-shadow var(--t-fast) var(--ease);
}
.kit-col:hover{transform:scale(1.16);}
.kit-col.on{box-shadow:0 0 0 2px var(--accent);}
.kit-cols.alt .kit-col{width:18px;height:18px;padding:3px;}
@media(max-width:860px){ .kit-cols.alt{display:none;} }

/* ---------- 26c. gameday's own proportions ----------
   The people are the screen, so they get the room: the eleven and the bench
   run the full width under the strip, and the notepad and the pencil sit
   beside the log below them. The doors stop being four boxed cards and
   become what they are — four places to go, on one line. */
@media(min-width:900px){
  .gd-grid{grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:var(--s-6);}
}
.gd-people{grid-column:1 / -1;margin-bottom:var(--s-5);}
.gd .gd-grid{margin-top:var(--s-5);}
.gdf-wall > p{grid-column:1 / -1;margin:0;}

.gd-doors{
  display:flex;gap:var(--s-2);flex-wrap:wrap;
  padding:var(--s-3) 0;border-bottom:1px solid var(--line);
}
.gd-door{
  flex-direction:row;align-items:center;gap:var(--s-2);
  padding:0 var(--s-3);min-height:44px;
  background:none;border:0;border-radius:var(--r-md);
  transition:background var(--t-fast) var(--ease);
}
.gd-door:hover{background:var(--surface-2);box-shadow:none;}
.gd-door span{font-weight:var(--w-emph);font-size:var(--fs-base);}
.gd-door small{color:var(--ink-3);}
.gd-door svg{color:var(--ink-3);}
.gd-door:hover svg{color:var(--accent);}
@media(max-width:900px){ .gd-doors{overflow-x:auto;flex-wrap:nowrap;} .gd-door{flex:none;} }


/* ============================================================
   27. ONE PLACE FOR THE PITCH.

   Eóin, 8 Sep 2026: "a lot of the app is repeating itself — a lot
   of tactics boards, a lot of design areas… it should be easy to
   zoom in and then zoom out of any part."

   Five screens put something on a pitch: the team sheet, the
   board, an activity, a set piece and a telestration. They were
   across two doors and a folder, each with its own way in and no
   way across, and the Design Lab carried a second three-way
   switcher of its own on top of that. One door, one strip, drawn
   by the shell so it is in the same place on all five and cannot
   drift. Nothing was rebuilt: the five screens are the same five
   screens, they just stopped hiding from each other.
   ============================================================ */
.modes{
  display:flex;gap:2px;flex-wrap:wrap;
  margin:0 0 var(--s-5);padding-bottom:var(--s-2);
  border-bottom:1px solid var(--line);
}
.mode{
  display:flex;flex-direction:column;align-items:flex-start;gap:1px;
  padding:8px var(--s-3);min-height:44px;border-radius:var(--r-md);
  background:none;text-align:left;position:relative;
  transition:background var(--t-fast) var(--ease);
}
.mode:hover{background:var(--surface-2);}
.mode-l{
  font-size:var(--fs-md);font-weight:500;color:var(--ink-2);
  letter-spacing:-.005em;
}
.mode-h{font-size:var(--fs-xs);color:var(--ink-3);}
.mode.on .mode-l{color:var(--ink);font-weight:var(--w-emph);}
.mode.on::after{
  content:"";position:absolute;left:var(--s-3);right:var(--s-3);bottom:calc(var(--s-2) * -1 - 1px);
  height:2px;border-radius:var(--r-capsule);background:var(--accent);
}
@media(max-width:760px){
  .modes{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;}
  .modes::-webkit-scrollbar{display:none;}
  .mode{flex:none;}
  .mode-h{display:none;}
}

/* ---------- 27b. settings ----------
   Named colours in a list, not a row of anonymous dots. This is the one
   screen where a coach is choosing rather than working, so the control can
   afford to say what it is. */
.set-cols{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:var(--s-2);margin-top:var(--s-4);}
.set-col{
  display:flex;align-items:center;gap:var(--s-3);
  min-height:52px;padding:0 var(--s-3);border-radius:var(--r-md);
  background:none;text-align:left;
  transition:background var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease);
}
.set-col .dot{
  width:22px;height:22px;border-radius:50%;flex:none;background:var(--c);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.14);
}
.set-col .nm{font-size:var(--fs-md);color:var(--ink-2);}
.set-col:hover{background:var(--surface-2);}
.set-col.on{box-shadow:inset 0 0 0 2px var(--accent);}
.set-col.on .nm{color:var(--ink);font-weight:var(--w-emph);}


/* ============================================================
   28. STATE IS A CONTRACT.

   Eóin: "as if Apple bought my company and wants to revamp how
   it looks and feels."

   The thing that separates software that works from software
   that feels expensive is not a palette — it is that every
   control answers the same way, every time, on every screen.
   This app had FIVE focus rings and which one you got depended
   on your tag name; FOUR press scales; THREE disabled opacities,
   with the same `.pill` primitive picking two different ones
   depending on whether the call site used an attribute or an
   ARIA state.

   So this section is written against BEHAVIOUR, not against
   class names: `[data-act]`, `button`, `a[href]`, the form
   controls. There are 328 elements carrying 207 actions through
   one delegated handler in this app, which is what turns a
   refactor into one section. A rule written here is inherited by
   every screen built after it, including the ones nobody has
   thought of.
   ============================================================ */
.act,
[data-act]:not(.modal-overlay):not(.cmd-scrim):not(.sheet-scrim),
button, a[href], input, select, textarea, label.linklike{
  -webkit-tap-highlight-color:transparent;
  touch-action:manipulation;
}

/* ONE focus ring. It was five, and which you got depended on your tag. */
[data-act]:focus-visible,
button:focus-visible, a[href]:focus-visible, [tabindex]:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible, .field:focus-visible{
  outline:2px solid var(--accent);
  outline-offset:2px;
  border-radius:var(--r-xs);
  box-shadow:none;
}
input:focus-visible,select:focus-visible,textarea:focus-visible,.field:focus-visible{
  border-color:var(--accent);
}

/* ONE press: 3% in at 90ms, spring back over 250. Brief §4. */
[data-press]{
  transform:scale(.97) !important;
  transition-duration:90ms !important;
}
[data-press]:not(.gd-whistle):not(.modal-overlay){
  background-image:radial-gradient(120px 120px at var(--px,50%) var(--py,50%),
                   rgba(var(--accent-rgb),.14), transparent 62%);
}

/* ONE disabled treatment. It was three opacities. */
:disabled,[aria-disabled="true"]{
  color:var(--ink-3) !important;
  background:var(--surface-2) !important;
  box-shadow:none !important;
  cursor:default;
  opacity:1;
}
:disabled svg,[aria-disabled="true"] svg{color:var(--ink-3) !important;}

/* THE 44pt FLOOR, restored. `.pill{min-height:34px}` in §24 was unguarded and
   loaded after the coarse-pointer rule in hub.html, so all seventy-five pills
   were 34px on the one device the floor exists for. */
@media (pointer:coarse){
  [data-act],.pill,.btn,.icon-btn,.seg button,
  input,select,textarea,.rail-find,.team-cur,.team-other,
  nav .nav-btn,nav .nav-sub-btn,.mode{
    min-height:44px;
  }
}

/* HOVER IS FOR A CURSOR. iOS applies :hover on tap and HOLDS it, so the last
   thing a coach touched stayed lit — the app looked like it had selected
   something he did not select. */
@media (hover:none),(pointer:coarse){
  .card.hoverable:hover,.day:hover,.pl:hover .pl-face,.gdf:hover .gdf-face,
  .cmd-row:hover,.needs-row:hover,.next-session:hover,.mode:hover,
  .set-col:hover,.kit-pat:hover,.kit-col:hover,.swatch:hover,.gd-door:hover,
  .mode-btn:hover,.rail-find:hover,.team-other:hover,nav .nav-btn:hover,
  nav .nav-sub-btn:hover,.btn-quiet:hover,.what:hover{
    background:inherit;transform:none;border-width:inherit;padding-left:0;
  }
}
/* Two rules that reflow under the cursor: a hover that moves text is worse
   than a hover that does not exist. Brief §4 bans hover transforms. */
.needs-row:hover,.next-session:hover{padding-left:0;}

/* A PANEL SCROLLS ITSELF, not the page behind it. */
nav,#main,.modal,.gd-log,.cmd-list,.tbf-rail,.mw-list,.lu-chips,.dz-fly{
  overscroll-behavior:contain;
}

/* Something that acts, looks like it. */
[data-act]{cursor:pointer;}
[data-act]:disabled,[data-act][aria-disabled="true"]{cursor:default;}


/* ============================================================
   29. THE WEEKEND, AS ONE THING.

   Eóin: "make it more of a seamless feeling to navigate the whole
   weekend."

   Seamless is not a transition. It is: the app knows what day it
   is, the way back always exists and is always in the same place,
   and coming back lands you where you left rather than at the top
   of the page. That last one is most of it in practice.
   ============================================================ */
.back{
  display:inline-flex;align-items:center;gap:4px;
  margin-bottom:4px;padding:4px 8px 4px 4px;border-radius:var(--r-capsule);
  background:none;color:var(--ink-3);
  font-size:var(--fs-sm);font-weight:500;line-height:1;
  transition:color var(--t-fast) var(--ease),background var(--t-fast) var(--ease),
             padding-right var(--t-base) var(--out);
}
.back svg{flex:none;}
.back:hover{color:var(--ink);background:var(--surface-2);}
.section-name{min-width:0;}

/* The weekend spine on Home: what the day is actually asking for. */
.spine{
  display:flex;align-items:center;gap:var(--s-3);flex-wrap:wrap;
  padding:var(--s-3) 0 0;
}
.spine-days{display:flex;gap:2px;align-items:center;}
.spine-day{
  display:flex;flex-direction:column;align-items:flex-start;gap:1px;
  min-height:44px;padding:4px var(--s-3);border-radius:var(--r-md);
  background:none;text-align:left;position:relative;
}
.spine-day .d{
  font-family:var(--display);font-weight:700;font-size:var(--fs-md);
  color:var(--ink-3);letter-spacing:-.01em;
}
.spine-day .w{font-size:var(--fs-xs);color:var(--ink-3);}
.spine-day.on .d{color:var(--ink);}
.spine-day.on .w{color:var(--accent-deep);font-weight:var(--w-emph);}
.spine-day.on::after{
  content:"";position:absolute;left:var(--s-3);right:var(--s-3);bottom:2px;
  height:2px;border-radius:var(--r-capsule);background:var(--accent);
}
.spine-day.done .d,.spine-day.done .w{opacity:.45;}

/* ---------- 29b. the score rolls, the event arrives ----------
   Brief §4: the digit that changed moves; the ones that did not, do not. And
   a line arriving in the log slides in from the minute it belongs to rather
   than appearing. Both are single elements — nothing else on the screen has
   any reason to know a goal was scored. */
.gd-goal.rolled{animation:gd-roll var(--t-slow) var(--spring);}
@keyframes gd-roll{
  0%{transform:translateY(38%) scale(.86);opacity:0}
  60%{opacity:1}
  100%{transform:none;opacity:1}
}
.gd-log .gd-ev.just-in{animation:gd-ev-in 340ms var(--out) both;}
@keyframes gd-ev-in{
  from{opacity:0;transform:translateX(-10px)}
  to{opacity:1;transform:none}
}
@media (prefers-reduced-motion: reduce){
  .gd-goal.rolled,.gd-log .gd-ev.just-in{animation:none;}
}

/* ---------- 29c. the marker travels ----------
   The current door was six separate bars with five of them hidden, so it
   blinked out of one row and into another. It is one element that moves,
   which is the difference between an app that switches and an app that goes
   somewhere. Positioned from the active row's own box after each render —
   two numbers and a transform, nothing per frame. */
#railMark{
  position:fixed;left:0;top:0;width:3px;z-index:45;
  border-radius:var(--r-capsule);background:var(--rail-accent);
  opacity:0;pointer-events:none;
  transition:transform var(--t-slow) var(--spring), height var(--t-slow) var(--spring),
             opacity var(--t-fast) var(--ease);
}
@media (prefers-reduced-motion: reduce){
  #railMark{transition:opacity var(--t-fast) var(--ease);}
}


/* ---------- 30. a day, entered by hand ----------
   The season plan is what the session planner plans against, and until this
   existed it could only be filled from a CSV pushed through a terminal or a
   club calendar subscription. This is a coach putting Thursday on his own
   schedule in four fields. */
.newday{max-width:none;margin-bottom:var(--s-5);}
.nd-kinds{display:flex;gap:4px;flex-wrap:wrap;margin-bottom:var(--s-4);}
.nd-row{display:flex;gap:var(--s-3);flex-wrap:wrap;margin-bottom:var(--s-3);}
.nd-f{display:flex;flex-direction:column;gap:4px;min-width:150px;flex:1;}
.nd-f.wide{flex-basis:100%;}
.nd-f span{font-size:var(--fs-sm);color:var(--ink-2);}
.nd-f input{min-height:44px;padding:0 var(--s-3);font-size:var(--fs-md);}


/* ---------- 31. the player, with his face ----------
   A coach taps a 76px face on the wall and used to land on a text header —
   the one thing the wall promises, missing at the moment it was earned. The
   face is also the way to GIVE a player one: luPickPhoto and luUploadPhoto
   were fully written, wired into the action table, and emitted by nothing in
   twelve thousand lines. */
.ph{display:flex;gap:var(--s-5);align-items:flex-start;flex-wrap:wrap;margin-bottom:var(--s-6);}
.ph-face{
  position:relative;width:112px;height:112px;border-radius:50%;flex:none;
  overflow:hidden;background:var(--surface-2);
  border:4px solid var(--accent);display:grid;place-items:center;
  box-sizing:border-box;padding:0;
  transition:border-width var(--t-fast) var(--ease),transform 250ms var(--spring);
}
.ph-face.gk{border-color:var(--gold-accent);}
.ph-face.out{filter:grayscale(1);border-color:var(--line-2);}
.ph-face img{width:100%;height:100%;object-fit:cover;object-position:50% 12%;display:block;}
.ph-ini{font-family:var(--display);font-weight:700;font-size:40px;color:var(--ink-3);}
.ph-cam{
  position:absolute;right:2px;bottom:2px;width:32px;height:32px;border-radius:50%;
  background:var(--surface);color:var(--ink-2);display:grid;place-items:center;
  box-shadow:0 0 0 2px var(--bg);opacity:0;
  transition:opacity var(--t-fast) var(--ease);
}
.ph-face:hover .ph-cam,.ph-face:focus-visible .ph-cam{opacity:1;}
@media (hover:none){ .ph-cam{opacity:1;} }
.ph-who{flex:1;min-width:240px;display:flex;flex-direction:column;gap:var(--s-3);}
.ph-facts{display:flex;align-items:baseline;gap:var(--s-3);flex-wrap:wrap;}
.ph-num{
  font-family:var(--display);font-weight:800;font-size:44px;line-height:1;
  letter-spacing:-.02em;color:var(--ink);font-variant-numeric:tabular-nums;
}
.ph-pos{font-family:var(--display);font-weight:700;font-size:var(--fs-xl);color:var(--ink-2);}
.ph-year{font-size:var(--fs-md);color:var(--ink-3);}
.ph-home{font-size:var(--fs-base);color:var(--ink-3);margin-top:-6px;}
.ph-target{
  width:100%;max-width:56ch;min-height:44px;padding:0 var(--s-3);
  font-size:var(--fs-md);
}

/* ============================================================
   §32  THE SESSION IS ONE SHEET

   Measured, 9 Sep 2026: one Wednesday's session screen was eight
   separate cards stacked down 3,370px, 87 controls, and seven
   paragraphs of instruction — a card border, radius and shadow
   around every part of what is, to a coach, a single document.
   Eight boxes is what a FORM looks like. A session is a DOCUMENT.

   So: one surface, hairline divisions, and hierarchy carried by
   type instead of by eight edges competing at the same margin.
   Nothing was removed and no field moved; the boxes went.
   ============================================================ */
.sheet{
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:var(--r-lg);
  box-shadow:var(--sh-2);
  overflow:hidden;
  margin-bottom:12px;
}
.sheet-top{
  padding:16px 20px 16px;
  background:var(--surface-2);
  border-bottom:1px solid var(--line);
}
.sheet-title{
  font-size:var(--fs-md);
  font-weight:var(--w-emph);
  letter-spacing:-.02em;
}
.sheet-lede{
  font-size:var(--fs-sm);
  line-height:1.6;
  color:var(--ink-2);
  margin:4px 0 0;
  max-width:76ch;
}
/* A part of the document, not a card of its own. The rule between two
   parts is the ONLY thing dividing them, and it starts at the text
   rather than the edge so the sheet reads as continuous paper. */
.sheet-sec{
  display:block;
  padding:16px 20px;
  border-top:1px solid var(--line);
}
.sheet-sec:first-of-type{ border-top:0; }
.sheet-sec.flush{ padding:0; }
.sheet-sec.over{ box-shadow:inset 3px 0 0 var(--amber); }

/* RETRACTED, 9 Sep 2026, same day it was written. This was tracked caps at
   11px — which is precisely what §"THE EYEBROW stops shouting" above deleted
   from eleven screens for being the loudest thing on them and saying the
   least. Glossing one screen in a language the other fourteen had already
   rejected is not a gloss, it is a second app. It is the card title's rule
   now, because that IS the settled rule: quiet, sentence case, a hairline. */
.sheet-h{
  display:flex;
  align-items:center;
  gap:8px;
  font-size:var(--fs-sm);
  font-weight:500;
  letter-spacing:0;
  text-transform:none;
  color:var(--ink-2);
  padding-bottom:8px;
  margin:0 0 var(--s-4);
  border-bottom:1px solid var(--line);
}
.sheet-h svg{ color:var(--ink-3); }

/* ONE MATERIAL. `.card` was defined three times across two files and `.sheet`
   was a fourth surface with its own radius and shadow. A sheet is not a new
   material — it is a card that holds sections, so it is made of the same
   thing and the only difference is what is inside it. */
.sheet{
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:var(--r-md);
  box-shadow:none;
}
.sheet-top{ background:var(--surface-2); }

/* Instruction, shown only when the ? in the heading is on. It reads as an
   annotation on the page rather than as content, because that is what it is:
   the app explaining itself to someone who asked.

   NAMED .help, NOT .hint — .hint was already taken, by the "hold to confirm"
   caption inside the matchday whistle, and this rule's left border and
   padding were landing on it. A generic class name in a twelve-thousand-line
   file is a collision waiting for a screenshot to reveal it. */
.help{
  font-size:var(--fs-sm);
  line-height:1.55;
  color:var(--ink-2);
  margin:0 0 8px;
  padding-left:8px;
  border-left:2px solid var(--accent-line);
  max-width:74ch;
}

/* The status control wears its own answer: the colour IS the state, so the
   day reads at a glance without four buttons open to say it. */
.st-dot{
  width:8px;height:8px;border-radius:50%;
  display:inline-block;margin-right:8px;flex:none;
  box-shadow:0 0 0 2px var(--surface);
}
/* Season context on a single-day screen — one line, not the loudest card. */
.install-line{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:0 2px 12px;margin-bottom:2px;
  border-bottom:1px solid var(--line);
  font-size:var(--fs-sm);color:var(--ink-2);
}
.install-line .il-live{ color:var(--ink); font-weight:var(--w-emph); }
.install-line .il-vs{
  font-size:var(--fs-sm);font-weight:500;color:var(--ink-3);
}

/* Previous · Today · Next is ONE control with three parts, not three controls
   the header's space-between can scatter across the bar. */
.stepper{
  display:inline-flex;align-items:center;gap:2px;
  background:var(--surface-2);
  border:1px solid var(--line);
  border-radius:var(--r-capsule);
  padding:2px;
}
.stepper .btn{ border:0; background:transparent; box-shadow:none; }
.stepper .btn-sm{ min-width:32px; padding:0 var(--s-2); font-size:var(--fs-md); }

/* The day's own facts, as the head of the sheet its session lives in. */
.day-line{display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;align-items:baseline;}
.day-call{font-size:var(--fs-md);font-weight:var(--w-emph);letter-spacing:-.02em;}
.day-tags{display:flex;gap:4px;flex-wrap:wrap;}
.day-when{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap;margin-top:8px;}
.day-at{font-size:var(--fs-md);font-weight:var(--w-emph);}
.day-venue{font-size:var(--fs-base);color:var(--ink-2);}
.day-focus{font-size:var(--fs-base);line-height:1.65;margin:8px 0 0;max-width:76ch;}
.day-flag{font-size:var(--fs-sm);color:var(--amber);margin-top:8px;line-height:1.55;}
.sheet-top .kv{margin-top:4px;}
.sheet-top .day-note{margin-top:8px;}
/* The one division inside the head: above it is the day, below it the session
   that day contains. A rule, not a second box. */
.sheet-rule{height:1px;background:var(--line-2);margin:12px 0 12px;}

/* ------------------------------------------------------------------
   The trail is a trail, not a row of buttons.

   Three chunky bordered pills took 140px of a phone before any content
   began, and wrapped onto three lines — for a control whose whole job is
   to say quietly where you are. It is type with separators now, at the
   label size, and the current level is simply the one that is not a link.
   The 44pt floor still applies to the two that ARE links, carried by the
   line box rather than by a border.
   ------------------------------------------------------------------ */
.crumbs{ gap:4px; margin-bottom:12px; }
.crumb{
  font-size:var(--fs-sm);
  font-weight:600;
  color:var(--ink-3);
  padding:4px 2px;
  background:transparent;
  border:0;
  border-radius:var(--r-xs);
  letter-spacing:-.005em;
}
.crumb:not(.here):hover{ color:var(--accent-deep); background:transparent; }
.crumb.here{
  color:var(--ink);
  background:transparent;
  border:0;
}
.crumb-sep{ color:var(--ink-3); opacity:.5; font-size:var(--fs-sm); }
@media (pointer:coarse){
  /* the target grows, the ink does not */
  .crumb{ padding:12px 4px; }
}

/* ============================================================
   §33  THE INVARIANTS

   Eóin, 9 Sep 2026: "when I use an Apple product — shape, touch,
   colour, glass — it all gives me the same elegant feeling."

   That feeling is not a style. It is a small number of rules
   applied WITHOUT EXCEPTION, so nothing on any screen is making
   its own decision. Measured here before this section was
   written: 39 distinct spacing values across 704 uses, sixteen
   of them off any grid; five transition durations where the
   token file defines three; a heading language that disagreed
   with itself. The screens felt different because they WERE
   different — every one had been spaced by hand.

   The grid is fixed in the markup (all 519 values snapped to
   multiples of 4). What is left is geometry, and Apple's own
   Layout guidance names it: CONCENTRICITY — "by aligning radii
   and margins around a shared centre, shapes nest comfortably" —
   and the CONTINUOUS corner curve, the squircle, rather than a
   circular arc.
   ============================================================ */

/* CONCENTRIC NESTING. A rounded thing inside a rounded thing shares its
   centre of curvature: inner radius = outer radius − the gap between them.
   Get it wrong and the corners read as almost-aligned, which the eye finds
   worse than obviously different. Where the padding exceeds the outer
   radius the honest inner radius is zero — which is why a list inside a
   rounded card has square rows on iOS, and why ours do now. */
.sheet > .sheet-sec{ border-radius:0; }
.sheet > .sheet-top{ border-radius:calc(var(--r-md) - 1px) calc(var(--r-md) - 1px) 0 0; }
/* the stepper: 2px of padding inside a capsule, so the inner is a capsule too */
.stepper .btn{ border-radius:var(--r-capsule); }
/* a control sitting directly on a card's padding edge */
.card.pad > .seg:first-child,
.card.pad > .pill-row:first-child{ border-radius:calc(var(--r-md) - var(--s-5)); }

/* THE CONTINUOUS CORNER. Apple's shapes are squircles, not circular arcs —
   the curvature eases in instead of starting abruptly, which is most of why
   their rounded rectangles look softer at the same radius. Progressive: a
   browser without it draws exactly what it drew before, so this can only
   improve the picture and can never break it. */
@supports (corner-shape: squircle){
  .card, .sheet, .btn, .pill, .tag, .modal, .field,
  input[type=text], input[type=url], input[type=date], input[type=number],
  input[type=email], select, textarea{
    corner-shape: squircle;
  }
}

/* ONE LIGHT SOURCE. Every shadow in the app falls from the same place —
   directly above and slightly behind — because depth here means one thing
   only: this floats over that. Both tokens are already shaped that way
   (0 x-offset, positive y); this states the rule so a future shadow cannot
   quietly invent a second lamp. Nothing that a coach READS is allowed to
   float: the shadow budget is spent on chrome, and nowhere else.
       --sh-1  a hairline lift   --sh-2  a floating surface
   No other box-shadow may be written. */

/* ============================================================
   §34  THE RE-GLOSS

   Eóin, 9 Sep 2026: "it still feels kind of tacky."

   He is right, and the audit says why in numbers: 188 of 431
   interactive elements — 44% — had no press state at all. The
   back button on every screen. The mode strip on all six board
   screens. Sixty-six Design Lab swatches. Home's entire content.
   The app LOOKED consistent and felt dead under the finger, and
   nothing reads as cheap faster than a control that does not
   answer you.

   The other two are register, not polish:

   ONE TYPEFACE. Big Shoulders — a condensed poster face at
   weight 700–800 — was doing the work of a UI face on every
   heading in the app. That is a sports-flyer voice, and it is
   most of what "tacky" means here. Apple ships ONE family and
   varies weight and optical size; the drama comes from the
   hierarchy, never from a second personality. The display face
   retreats to the only place it is honestly earned: figures a
   coach reads at a glance from arm's length — a score, a clock,
   a count — where condensed IS the right tool.

   NEUTRAL CHROME, handled in tokens.css above.
   ============================================================ */

/* ---- 1. NOTHING IS DEAD UNDER THE FINGER --------------------------------
   One rule, everything that can be pressed. A control must acknowledge the
   touch BEFORE it does anything else — that acknowledgement is the whole
   sensation of a thing being well made. Two registers, because a 34px pill
   and a whole day card should not behave alike: small controls take the
   press geometrically, large surfaces take it as light. */
[data-act], button, [role="button"], .crumb, .back, .mode, .day, .spine-day,
.needs-row, .next-session, .set-col, .gd-door, .gdf, .dz-sw, .dz-railbtn,
.dz-galcard, .call-card, .pl{
  -webkit-tap-highlight-color:transparent;
  transition:transform 250ms var(--spring), background-color var(--t-fast) var(--ease),
             border-color var(--t-fast) var(--ease), opacity var(--t-fast) var(--ease);
}
/* small controls: the press is geometric */
.back:active, .mode:active, .crumb:active, .dz-sw:active, .dz-railbtn:active,
.gdf:active, .tag[data-act]:active, .st-dot:active{
  transform:scale(.94);
  transition-duration:90ms;
}
/* large surfaces: the press is light, never a squeeze */
.day:active, .spine-day:active, .needs-row:active, .next-session:active,
.set-col:active, .gd-door:active, .dz-galcard:active, .call-card:active,
.card.hoverable:active, .sheet-sec [data-act]:active{
  background:var(--surface-2);
  transition-duration:60ms;
}
/* the catch-all: anything actionable this file has not named still answers */
[data-act]:active:not(.modal-overlay):not(.cmd-scrim):not(canvas):not(svg):not(.dz-stage){
  opacity:.72;
  transition-duration:60ms;
}
/* a finger is not a mouse: the press must land even mid-scroll */
@media (pointer:coarse){
  [data-act]:active{ transition-duration:0ms; }
}
/* reduced motion keeps the ANSWER and drops only the movement */
@media (prefers-reduced-motion:reduce){
  .back:active, .mode:active, .crumb:active, .dz-sw:active, .dz-railbtn:active,
  .gdf:active, .tag[data-act]:active, .st-dot:active{
    transform:none; background:var(--surface-2);
  }
}

/* ---- 2. ONE TYPEFACE ----------------------------------------------------
   Headings speak in the body face, heavier and tighter. The hierarchy is
   carried by weight, size and tracking — which is the only place it should
   ever have come from. */
h1, h2, h3, .section h1, .day-sum-title, .home-h1{
  font-family:var(--body);
  font-weight:640;
  letter-spacing:-.024em;
}
/* The display face keeps exactly what it earns: figures read at a glance,
   from arm's length, on a touchline. Nothing else. */
.glance-v, .gd-score, .gd-clock, .gd-min, .call-num, .lab .n,
.stat-val, .metric .v, .brand-title, .door-word{
  font-family:var(--display);
  font-variant-numeric:tabular-nums;
}

/* ============================================================
   §35  ONE VOICE

   §34 retired the condensed face from h1/h2/h3 and missed the
   thirty other places it was doing interface work — including
   the NAVIGATION LABELS. Home, Calendar, Create, Matchday, More
   were set in a 700-weight poster face. So were the day cards
   ("Training", "Game"), the fixture line, the team names on
   Matchday, the command bar and the front door.

   A condensed display cut is a headline face. Used on furniture
   it reads as a flyer for the match rather than the instrument
   you run the week with, and that — more than any colour — is
   what "tacky" was. Apple ships one family and gets its drama
   from weight, size and tracking alone.

   The face is not dropped. It keeps the two jobs it is actually
   the best tool for: the wordmark, and FIGURES a coach reads at
   a glance from ten yards in the rain — the score, the clock, a
   jersey number, a count. Everything a coach READS is the body
   face now.
   ============================================================ */
.section h1, .section.home h1, .day-sum-title, .door-h, .cmd-form,
nav .nav-btn, nav .nav-sub-btn,
.fixture-line, .day .d, .spine-day .d, .ns-when b,
.gd-name, .gd-crest.them, .ph-pos, .ko{
  font-family:var(--body);
  font-weight:640;
  letter-spacing:-.022em;
}
/* Nav labels sit at label size and want a touch less weight than a heading:
   a sidebar is a list of places, not a list of announcements. */
nav .nav-btn, nav .nav-sub-btn{
  font-weight:560;
  letter-spacing:-.012em;
}
nav .nav-btn.active, nav .nav-sub-btn.active{ font-weight:660; }

/* The display face, and the complete list of what earns it. Anything not
   named here is the body face — that is the rule, not a preference. */
.brand-title, .door-word,
.gd-nums, .gd-clock-num, .gd-clock, .gd-score, .gd-min, .gd-goal, .gd-dash,
.gd-whistle, .gd-log .gd-ev-min, .gdf-num, .gdf-ini,
.call-num, .home-list .call-num, .glance-v, .stat-val, .metric .v,
.lab .n, .mw-count, .pl-ini, .pl-meta b, .ph-ini, .ph-num{
  font-family:var(--display);
}
/* Figures a coach compares must line up, always. */
.gd-clock, .gd-score, .gd-min, .gd-goal, .call-num, .glance-v, .stat-val,
.metric .v, .lab .n, .mw-count, .pl-meta b, .ph-num, .gd-log .gd-ev-min{
  font-variant-numeric:tabular-nums;
}

/* ============================================================
   §36  LIQUID GLASS

   Eóin asked for it by name. It is worth being precise about
   what it is, because "glass" in most web UI means one blur and
   a white overlay, and that is frosted plastic.

   Apple's material is FIVE optical behaviours stacked:
     1. translucency + blur   — the backdrop shows through, softened
     2. refraction            — the edge BENDS the backdrop like a lens
     3. chromatic aberration  — R and B bend by different amounts, so
                                the rim carries a faint colour fringe
     4. specular light        — a directional highlight from one lamp
     5. the fresnel edge      — a bright hairline where the glass ends,
                                brightest where the surface turns away

   1, 3, 4 and 5 are reachable in any browser with gradients and
   shadows. 2 is not: no CSS filter function displaces a pixel, so
   real refraction needs an SVG feDisplacementMap referenced from
   backdrop-filter — and only Chromium accepts that. It is behind
   @supports; Safari and Firefox get the other four and the same
   blur they had. This is stated rather than hidden because a
   material that silently does nothing on half the world's
   browsers is worse than one that admits its floor.

   WHERE. Chrome only, and only chrome that has real content
   moving underneath it — a material that refracts a solid colour
   is an expensive way to draw a solid colour. That is the same
   rule §2 of this file already set, and Apple's own: glass is
   for the layer ABOVE your content, never the content.
   ============================================================ */

:root{
  /* the lamp: above and slightly left, the same one every shadow uses */
  --lg-spec:210deg;
  --lg-rim-lit:rgba(255,255,255,.92);
  --lg-rim-shade:rgba(35,33,29,.14);
  --lg-fringe-warm:rgba(255,214,170,.22);
  --lg-fringe-cool:rgba(170,214,255,.22);
}
:root[data-theme="dark"]{
  --lg-rim-lit:rgba(255,255,255,.22);
  --lg-rim-shade:rgba(0,0,0,.34);
  --lg-fringe-warm:rgba(255,196,130,.14);
  --lg-fringe-cool:rgba(130,196,255,.14);
}

/* The material. Applied to a surface that ALREADY carries the blur, so this
   only adds the four optical layers the blur was missing. */
.lg{
  position:relative;
  isolation:isolate;
  /* 4 + 5: the lamp above-left, and the fresnel hairline. Both as inset
     shadows so they paint on the border box and cannot scroll away. */
  box-shadow:
    inset 0 1px 0 0 var(--lg-rim-lit),
    inset 1px 0 0 0 var(--lg-rim-lit),
    inset 0 -1px 0 0 var(--lg-rim-shade),
    inset -1px 0 0 0 var(--lg-rim-shade),
    var(--sh-lift-2);
}
/* 3: chromatic aberration. Two hairlines, one warm and one cool, on the two
   edges light leaves by. It is almost subliminal at these alphas, and that is
   the point — you should not be able to name it, only notice the surface
   looks like a material rather than a rectangle. */
.lg::after{
  content:"";
  position:absolute;
  inset:0;
  border-radius:inherit;
  pointer-events:none;
  z-index:1;
  background:
    linear-gradient(var(--lg-spec), var(--lg-fringe-cool) 0 1.5px, transparent 1.5px),
    linear-gradient(calc(var(--lg-spec) + 180deg), var(--lg-fringe-warm) 0 1.5px, transparent 1.5px);
  mix-blend-mode:screen;
}
:root[data-theme="dark"] .lg::after{ mix-blend-mode:plus-lighter; }

/* 2: REFRACTION. Chromium only. The lens is composited on the GPU, so it
   costs a texture rather than a repaint — but it is still the most expensive
   thing in the stylesheet, which is why it reaches exactly three surfaces. */
@supports (backdrop-filter: url(#suilLens)){
  .lg.lg-refract{
    -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat)) url(#suilLens);
            backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat)) url(#suilLens);
  }
}

/* WHO GETS IT. Three surfaces, and each one has the page genuinely running
   underneath it: the bar on a phone, the drawer that slides over the page,
   and the command bar. The desktop rail sits BESIDE the page and is
   deliberately excluded — there is nothing behind it to bend, and a lens over
   a flat colour is an expensive way to draw a flat colour. */
.topbar-mobile, .cmd, #sidebar.open{
  position:relative;
  isolation:isolate;
  box-shadow:
    inset 0 1px 0 0 var(--lg-rim-lit),
    inset 1px 0 0 0 var(--lg-rim-lit),
    inset 0 -1px 0 0 var(--lg-rim-shade),
    inset -1px 0 0 0 var(--lg-rim-shade),
    var(--sh-lift-2);
}
.topbar-mobile::after, .cmd::after{
  content:"";
  position:absolute;
  inset:0;
  border-radius:inherit;
  pointer-events:none;
  z-index:1;
  background:
    linear-gradient(var(--lg-spec), var(--lg-fringe-cool) 0 1.5px, transparent 1.5px),
    linear-gradient(calc(var(--lg-spec) + 180deg), var(--lg-fringe-warm) 0 1.5px, transparent 1.5px);
  mix-blend-mode:screen;
}
:root[data-theme="dark"] .topbar-mobile::after,
:root[data-theme="dark"] .cmd::after{ mix-blend-mode:plus-lighter; }

@supports (backdrop-filter: url(#suilLens)){
  .topbar-mobile, .cmd{
    -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat)) url(#suilLens);
            backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat)) url(#suilLens);
  }
  @media(max-width:860px){
    #sidebar.open{
      -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat)) url(#suilLens);
              backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat)) url(#suilLens);
    }
  }
}

/* ACCESSIBILITY IS NOT AN AFTERTHOUGHT HERE. A person who has asked their
   system to reduce transparency has asked for exactly this to stop. The
   material collapses to a solid surface and keeps every border and shadow
   that carried meaning — nothing becomes unreadable, and nothing moves. */
@media (prefers-reduced-transparency: reduce){
  .lg, .lg.lg-refract, .topbar-mobile, .cmd, .toast, .modal-overlay, #sidebar.open{
    -webkit-backdrop-filter:none !important;
            backdrop-filter:none !important;
  }
  .lg::after, .topbar-mobile::after, .cmd::after{ display:none; }
  .topbar-mobile{ background:var(--bg); }
  .toast{ background:var(--ink); }
  .modal-overlay{ background:rgba(25,25,20,.62); }
  #sidebar.open{ background:var(--rail); }
}
/* Sun mode is the touchline: direct sunlight, and every translucent surface
   becomes a smear. It already kills the blur; it kills the optics too. */
:root[data-sun="on"] .lg::after,
:root[data-sun="on"] .topbar-mobile::after,
:root[data-sun="on"] .cmd::after{ display:none; }
:root[data-sun="on"] .lg{ box-shadow:var(--sh-2); }

/* ============================================================
   §37  THE SURGERY — SEPARATION BY SPACE, NOT BY BOXES

   Anthropic's interface, and Apple's, share one habit that most
   web apps do not: they almost never draw a line around a group.
   Grouping is done with SPACE and, occasionally, with a whisper
   of a background step. Súil was doing the opposite — fifty
   cards, each with a border and a radius, so a screen presented
   the eye with fifty objects to parse before it could read a
   word. That is the whole difference between an app that feels
   considered and one that feels assembled.

   Deductively: a border's only job is to say "these things are
   together, and those are not". Whitespace already says that,
   costs nothing, and does not add an object. So the border is
   redundant everywhere the spacing is correct — and §33 made the
   spacing correct. The lines come out.

   What KEEPS a line: a genuine container whose edge is real (the
   session sheet, a modal), and rows inside a list, where the
   line separates peers rather than framing them.
   ============================================================ */

/* A card is a group, not an object. No border, no shadow, no frame — it is
   the same paper as the page, and the space around it does the grouping. */
.card{
  background:transparent;
  border:0;
  box-shadow:none;
}
/* A card that is genuinely a SURFACE — something rests on it, or it must be
   told apart from the paper behind — takes the paper tone and still no line. */
.card.pad,
.card.hoverable,
.alert-card{
  background:var(--surface);
  border:0;
}
/* Two real containers keep an edge, because their edge is real: the sheet
   holds sections that must read as inside it, and a modal floats. */
.sheet{ border:1px solid var(--line); background:var(--surface); }
.modal{ border:0; }

/* AIR. Anthropic's product surfaces breathe; ours were tight because the
   borders were doing the separating and space was only a gap. With the
   lines gone the space has to carry it, so it is given room to. */
.card.pad{ padding:var(--s-5) var(--s-5) calc(var(--s-5) + var(--s-1)); }
.sheet-sec{ padding:var(--s-5); }
.sheet-top{ padding:var(--s-5); }
.section{ --sec-air:var(--s-5); }
p, .meta, .day-focus, .sheet-lede{ line-height:1.65; }

/* Lists keep their hairlines — a line between PEERS is information; a line
   AROUND a group is decoration. Inset from the left so it starts at the
   text, which is the iOS grouped-list detail that makes a list read as one
   object instead of a stack of stripes. */
.sheet-sec + .sheet-sec{ border-top:1px solid var(--line); }
.lu-imp label + label,
.needs-row + .needs-row{ border-top:1px solid var(--line); }

/* The one accent rule, unchanged and now load-bearing: with the furniture
   neutral and the borders gone, the team's colour is the only saturated
   thing on the page — so it can only mean "this is the action" or "you are
   here". Colour that is everywhere means nothing; colour that appears twice
   on a screen means exactly what it says. */

/* The tactics board's two faces. Subordinate to the mode strip above it —
   a switch INSIDE a place, not another place. */
.faces{
  display:flex; gap:2px; margin:calc(var(--s-1) * -1) 0 var(--s-3);
  background:var(--surface-2); border-radius:var(--r-capsule);
  padding:2px; width:fit-content;
}
.face{
  border:0; background:transparent; cursor:pointer;
  font:inherit; font-size:var(--fs-sm); font-weight:560;
  color:var(--ink-2); padding:0 var(--s-3); min-height:32px;
  border-radius:var(--r-capsule);
  transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.face.on{ background:var(--surface); color:var(--ink); font-weight:660; box-shadow:var(--sh-1); }
.face:active{ transform:scale(.96); transition-duration:90ms; }
@media (pointer:coarse){ .face{ min-height:44px; } }

/* The kit bar's side switch */
.kit-side{ display:flex; gap:2px; margin-right:var(--s-2); }

/* The board's own toolbar: the two controls a coach touches while looking at
   the pitch, and one button for everything he does not. */
.lu-tools{
  display:flex; align-items:center; gap:var(--s-2);
  flex-wrap:wrap; margin-bottom:var(--s-2);
}
.lu-bar.folded{ display:none; }


/* ============================================================
   §38  THE LAST OF THE SMALL THINGS — 10 September 2026

   Found by walking every screen of the running app rather than
   reading it. Each is one rule.
   ============================================================ */

/* A day with nothing on it is not a day OFF. "Off" is a call the plan
   makes; an empty day says so in the quieter ink, at a lighter weight,
   so the week's real decisions stand out from its gaps. */
.day.is-empty .d{color:var(--ink-3);font-weight:600;}

/* The two empty-state headlines that were still set in a serif. One
   display face across the whole product; the serif token is retired. */
.empty-title{
  font-family:var(--display);font-weight:700;font-size:24px;line-height:1.1;
  letter-spacing:-.005em;color:var(--ink);margin:12px 0 4px;
}

/* The calendar's three filters are ON by default, and an "on" pill was
   painted solid ink — so the month opened under three black buttons that
   read as the most important things on the screen. A filter that is on is
   the normal state and should look like nothing; one that is off is the
   exception, and goes quiet. Month / List keep their own lens style. */
.cal-controls .pill:not(.lens){background:transparent;border-color:transparent;color:var(--ink-3);}
.cal-controls .pill:not(.lens).active{background:var(--surface-2);border-color:transparent;color:var(--ink);}

/* THE FOOT OF THE RAIL, FOLDED. The account is one row that opens upward;
   the two mode buttons and the sync line sit above it. Everything that used
   to be a permanent line of chrome is one tap away, in the same place. */
.side-foot{padding:var(--s-3);}
.side-foot .sync{margin:0 0 var(--s-2) 8px;}
.side-modes{margin-bottom:var(--s-2);}
.acct{position:relative;}
.acct-cur{
  display:flex;align-items:center;gap:var(--s-2);width:100%;
  min-height:44px;padding:0 8px;border-radius:var(--r-md);
  color:var(--on-rail);text-align:left;
  transition:background var(--t-fast) var(--ease);
}
.acct.open .acct-cur{background:var(--rail-2);}
@media (hover:hover) and (pointer:fine){ .acct-cur:hover{background:var(--rail-2);} }
.acct-ini{
  width:28px;height:28px;border-radius:50%;flex:none;display:grid;place-items:center;
  background:var(--rail-on);color:var(--rail-on-ink);
  font-size:var(--fs-xs);font-weight:700;letter-spacing:.02em;
}
.acct-who{flex:1;min-width:0;display:flex;flex-direction:column;line-height:1.2;}
.acct-name{font-size:var(--fs-base);font-weight:var(--w-emph);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.acct-role{font-size:var(--fs-xs);color:var(--on-rail-2);}
.acct-chev{color:var(--on-rail-2);flex:none;transition:transform var(--t-base) var(--out);}
.acct.open .acct-chev{transform:rotate(180deg);}
.acct-menu{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--t-base) var(--out);}
.acct.open .acct-menu{grid-template-rows:1fr;}
.acct-menu>div{overflow:hidden;padding-bottom:var(--s-1);}
.acct-menu form{margin:0;}
.acct-item{
  display:flex;align-items:center;gap:var(--s-2);width:100%;
  min-height:36px;padding:0 8px;border-radius:var(--r-md);
  color:var(--on-rail-2);font-size:var(--fs-base);font-weight:500;
  text-decoration:none;cursor:pointer;text-align:left;
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease);
}
@media (hover:hover) and (pointer:fine){
  .acct-item:hover{background:var(--rail-2);color:var(--on-rail);}
  .acct-item.signout:hover{color:var(--red);}
}
@media (pointer:coarse){ .acct-item{min-height:44px;} }

/* The player before any rating: one line, one door. */
.player-unrated{margin-bottom:var(--s-6);}

/* THE SWATCHES ARE BEHIND THE SHIRT. The shirt is a button; the patterns
   and colours open under it as a small floating panel and go when it is
   tapped again. The bar above the pitch is one row again. */
.kit-bar{border-top:0;padding-top:0;}
.kit-anchor{position:relative;display:inline-flex;}
.kit-shirt{
  padding:0;border-radius:50%;cursor:pointer;
  transition:transform 250ms var(--spring),box-shadow var(--t-fast) var(--ease);
}
.kit-bar.open .kit-shirt{box-shadow:0 0 0 2px var(--accent);}
@media (pointer:coarse){ .kit-shirt{width:44px;height:44px;} }
.kit-fly{
  position:absolute;top:calc(100% + 8px);left:-8px;z-index:25;   /* under the sticky head (26) */
  display:none;flex-direction:column;gap:var(--s-2);width:max-content;
  padding:var(--s-3);border-radius:var(--r-md);
  background:var(--surface);box-shadow:var(--sh-lift);
}
.kit-bar.open .kit-fly{display:flex;}
/* An absolutely positioned panel shrinks to its narrowest item unless told
   otherwise, which stacked eight swatches one under another. Each row keeps
   its width; the panel takes the widest. */
.kit-fly .kit-pats,.kit-fly .kit-cols{flex-wrap:nowrap;}
@media(max-width:860px){ .kit-fly .kit-cols.alt{display:flex;} }

/* The mark top right and a screen's own actions were sharing the same
   corner: on the Tactics board the eye sat on top of "Clear board". The
   head keeps the mark's column clear, so nothing is ever under it. The head
   runs 36px past the section on each side (it is the sticky bar), so the
   clear column is measured from ITS edge: 24px of margin, 34px of mark, and
   the same 24px on the near side. */
@media(min-width:861px){ .section-head{padding-right:calc(34px + var(--s-5) * 2 + var(--s-1));} }


/* ============================================================
   §39  THE SEASON — 10 September 2026

   Fifteen weeks on one screen. Phases as bands, weeks as rows,
   seven quiet tiles across, and every game carrying its result
   once the whistle has gone. Training days are the team's colour
   at its softest; games are paper with a hairline, so the results
   are the only strong colour on the screen. The week we are in
   is the one row lit by the accent's whisper.
   ============================================================ */
.season{max-width:1180px;}
.sea-head{display:flex;align-items:flex-end;gap:var(--s-6);flex-wrap:wrap;padding:var(--s-2) 0 var(--s-4);}
.sea-stat{display:flex;flex-direction:column;}
.sea-n{font-family:var(--display);font-weight:700;font-size:44px;line-height:1;font-variant-numeric:tabular-nums;letter-spacing:0;}
.sea-l{font-size:var(--fs-sm);color:var(--ink-3);margin-top:2px;}
.sea-goals{font-size:var(--fs-base);color:var(--ink-2);padding-bottom:6px;}
.sea-next{margin-left:auto;text-align:right;display:flex;flex-direction:column;gap:2px;color:var(--ink-2);font-size:var(--fs-sm);}
.sea-next b{font-family:var(--display);font-weight:700;font-size:26px;line-height:1.05;color:var(--ink);letter-spacing:-.005em;}
.sea-range{font-size:var(--fs-sm);color:var(--ink-3);font-weight:500;}
.sea-week{
  display:grid;grid-template-columns:76px minmax(0,1fr);gap:var(--s-3);align-items:stretch;
  padding:5px 0;border-bottom:1px solid var(--line);
}
.sea-week.is-now{
  margin:0 calc(var(--s-2) * -1);padding-left:var(--s-2);padding-right:var(--s-2);
  border-radius:var(--r-sm);background:var(--accent-soft);border-bottom-color:transparent;
}
.sea-wk{display:flex;flex-direction:column;justify-content:center;line-height:1.15;}
.sea-wk b{font-family:var(--display);font-weight:700;font-size:var(--fs-lg);color:var(--ink);}
.sea-wk span{font-size:var(--fs-xs);color:var(--ink-3);}
.sea-days{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:4px;}
.sea-day{
  min-height:58px;padding:6px 8px;border-radius:var(--r-sm);text-align:left;
  display:flex;flex-direction:column;gap:1px;min-width:0;
  background:var(--surface-2);color:var(--ink-2);
  transition:background var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease);
}
.sea-day.is-off{background:transparent;color:var(--ink-4);}
.sea-day.is-rest{background:var(--surface-2);color:var(--ink-3);}
.sea-day.is-train{background:var(--accent-soft);color:var(--accent-deep);}
.sea-week.is-now .sea-day.is-train{background:var(--surface);}
.sea-day.is-game{background:var(--surface);box-shadow:inset 0 0 0 1px var(--line-2);color:var(--ink);}
.sea-day.is-today{box-shadow:inset 0 0 0 2px var(--accent);}
.sea-day.is-past{opacity:.8;}
.sea-day.is-off.is-past{opacity:1;}
.sea-day:hover{box-shadow:inset 0 0 0 1px var(--line-2);}
.sea-day.is-today:hover{box-shadow:inset 0 0 0 2px var(--accent);}
.sea-dow{font-size:var(--fs-xs);font-weight:500;white-space:nowrap;}
.sea-what{font-size:var(--fs-sm);font-weight:var(--w-emph);line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.sea-at{font-size:var(--fs-xs);color:var(--ink-3);margin-top:auto;}
.sea-res{font-family:var(--display);font-weight:700;font-size:var(--fs-md);letter-spacing:0;margin-top:auto;font-variant-numeric:tabular-nums;}
.sea-res.W{color:var(--accent-deep);} .sea-res.L{color:var(--red);} .sea-res.D{color:var(--ink-2);}
@media(max-width:860px){
  .sea-week{grid-template-columns:52px minmax(0,1fr);gap:var(--s-2);}
  .sea-days{gap:3px;}
  .sea-day{min-height:46px;padding:4px 5px;}
  .sea-dow{font-size:10px;}
  .sea-what{font-size:var(--fs-xs);}
  .sea-n{font-size:34px;}
  .sea-next{margin-left:0;text-align:left;width:100%;}
}


/* ============================================================
   §40  THE STAFF — 10 September 2026

   People as rows under a rule, not cards. A person's duties are
   small toggles on the row; the matchday sheet under them is read
   only, because it is the same fact turned round. Tasks are rows
   with a name on each, and each name is a light that moves.
   ============================================================ */
.staff-wall{display:flex;flex-direction:column;}
.stf{
  display:grid;grid-template-columns:40px minmax(150px,220px) minmax(0,1fr) auto;
  gap:var(--s-3);align-items:center;padding:var(--s-3) 0;border-bottom:1px solid var(--line);
}
.stf-ava{
  width:40px;height:40px;border-radius:50%;display:grid;place-items:center;
  background:var(--accent-soft);color:var(--accent-deep);
  font-weight:700;font-size:var(--fs-sm);letter-spacing:.02em;
}
.stf-who{display:flex;flex-direction:column;line-height:1.3;min-width:0;}
.stf-who b{font-weight:var(--w-emph);font-size:var(--fs-md);color:var(--ink);}
.stf-who span{font-size:var(--fs-sm);color:var(--ink-2);}
.stf-who a{font-size:var(--fs-xs);color:var(--ink-3);text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.stf-duties{display:flex;flex-wrap:wrap;gap:4px;}
.stf-acts{display:flex;gap:2px;}

/* A toggle the size of a word. Off is an outline; on is the one colour. */
.tog{
  font-size:var(--fs-xs);font-weight:500;padding:5px 10px;border-radius:var(--r-capsule);
  background:transparent;color:var(--ink-3);box-shadow:inset 0 0 0 1px var(--line-2);
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease);
}
.tog.on{background:var(--accent-deep);color:var(--on-accent);box-shadow:none;}
@media (hover:hover) and (pointer:fine){ .tog:not(.on):hover{color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink-3);} }
@media (pointer:coarse){ .tog{padding:8px 12px;font-size:var(--fs-sm);} }

.duty-sheet{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:0 var(--s-6);}
.duty{display:flex;justify-content:space-between;gap:var(--s-3);padding:9px 0;border-bottom:1px solid var(--line);font-size:var(--fs-base);}
.duty-name{color:var(--ink-2);}
.duty-who{font-weight:var(--w-emph);text-align:right;color:var(--ink);}
.duty.open .duty-who{color:var(--ink-4);font-weight:400;}

.task{display:flex;align-items:center;gap:var(--s-3);padding:8px 0;border-bottom:1px solid var(--line);}
.task-title{flex:1;min-width:0;text-align:left;font-size:var(--fs-base);font-weight:500;color:var(--ink);padding:0;}
.task.done .task-title{color:var(--ink-3);text-decoration:line-through;}
.task-who{display:flex;gap:4px;flex-wrap:wrap;justify-content:flex-end;}
.task-who .tog{color:var(--ink-2);}
.task-who .tog i{display:inline-block;width:6px;height:6px;border-radius:50%;margin-left:6px;background:var(--ink-4);vertical-align:1px;}
.task-who .tog.st-inprogress i{background:var(--amber);}
.task-who .tog.st-done{color:var(--ink-3);} .task-who .tog.st-done i{background:var(--accent);}
.task-add{padding:var(--s-3) 0 var(--s-4);border-bottom:1px solid var(--line);display:flex;flex-direction:column;gap:var(--s-2);}
.task-add input{width:100%;max-width:520px;}
.task-add .row-acts{margin-top:var(--s-1);}
.task-done{margin-top:var(--s-3);}
.task-done summary{font-size:var(--fs-sm);color:var(--ink-3);cursor:pointer;padding:6px 0;list-style:none;}
.task-done summary::-webkit-details-marker{display:none;}
@media(max-width:860px){
  .stf{grid-template-columns:36px minmax(0,1fr) auto;}
  .stf-ava{grid-row:1;}
  .stf-who{grid-row:1;}
  .stf-acts{grid-row:1;grid-column:3;}
  .stf-duties{grid-column:1 / -1;grid-row:2;}
  .stf-ava{width:36px;height:36px;}
}


/* ============================================================
   §41  THE MATCH WRITES ON THE PLAYER — 10 September 2026

   A card is a small card. Minutes sit under the face they belong
   to. The season's marks ride on the squad wall, and a man who
   sits out the next game says so wherever he is picked from.
   ============================================================ */
.gd-card{display:inline-block;width:9px;height:12px;border-radius:2px;vertical-align:-1px;}
.gd-card.y{background:var(--gold-accent);}
.gd-card.r{background:var(--red);}
.gd-evs{display:inline-flex;gap:4px;flex-wrap:wrap;}
.gd-ev.is-card .gd-ev-ico,.gd-ev.injury .gd-ev-ico{color:var(--ink-2);}
.gdf-min{font-size:var(--fs-xs);color:var(--ink-3);font-variant-numeric:tabular-nums;}
.mk{
  display:inline-grid;place-items:center;min-width:14px;height:14px;padding:0 3px;
  border-radius:3px;font-style:normal;font-size:10px;font-weight:700;line-height:1;
  margin-left:4px;vertical-align:1px;color:var(--on-solid);
}
.mk.y{background:var(--gold-accent);color:var(--on-gold);}
.mk.r{background:var(--red);color:var(--bg);}
.mk.s{background:var(--ink);color:var(--bg);letter-spacing:.02em;font-size:9px;}
.lu-flag{color:var(--red);}
.ph-season{font-size:var(--fs-sm);color:var(--ink-2);margin-top:4px;display:flex;gap:8px;align-items:center;flex-wrap:wrap;}


/* ============================================================
   §42  THE TRIP AND THE REPORT — 10 September 2026
   ============================================================ */
.trip{
  display:flex;align-items:center;gap:var(--s-2);flex-wrap:wrap;
  padding:10px 0;border-bottom:1px solid var(--line);font-size:var(--fs-base);color:var(--ink-2);
}
.trip svg{color:var(--ink-3);flex:none;}
.trip-line{flex:1;min-width:200px;}
.trip-empty{color:var(--ink-4);}
.trip-acts{display:inline-flex;gap:var(--s-2);align-items:center;}
.trip.on-gameday{margin:0 0 var(--s-4);}
.day-block .trip{max-width:640px;margin-top:var(--s-2);}

.gd-report{margin:0 0 var(--s-5);}
.gd-report .lab.rule{align-items:center;}
.rep-line{font-size:var(--fs-lg);font-weight:var(--w-emph);display:flex;gap:8px;align-items:baseline;flex-wrap:wrap;margin:var(--s-2) 0 var(--s-3);}
.rep-line b{font-family:var(--display);font-weight:700;font-size:28px;line-height:1;letter-spacing:0;font-variant-numeric:tabular-nums;}
.rep-res{font-size:var(--fs-xs);font-weight:700;letter-spacing:.06em;text-transform:uppercase;padding:3px 7px;border-radius:var(--r-xs);}
.rep-res.W{background:var(--accent-soft);color:var(--accent-deep);}
.rep-res.L{background:var(--red-soft);color:var(--red);}
.rep-res.D{background:var(--surface-2);color:var(--ink-2);}
.rep-row{display:grid;grid-template-columns:84px minmax(0,1fr);gap:var(--s-3);padding:6px 0;border-bottom:1px solid var(--line);font-size:var(--fs-base);}
.rep-k{color:var(--ink-3);}
.rep-v i{font-style:normal;color:var(--ink-3);font-variant-numeric:tabular-nums;}
.rep-mins{display:flex;flex-wrap:wrap;gap:4px 12px;padding:10px 0 0;}
.rep-min{font-size:var(--fs-sm);color:var(--ink-2);display:inline-flex;gap:5px;align-items:baseline;}
.rep-min b{font-family:var(--display);font-weight:700;font-size:var(--fs-md);color:var(--ink);font-variant-numeric:tabular-nums;letter-spacing:0;}

/* The spot illustration on an empty state: ink, with the one accent detail
   the drawing carries. Centred above the words, or in the crest's place. */
.spot{color:var(--ink-2);display:block;margin:0 auto var(--s-3);}
.fixture-crest .spot{margin:0;}
.empty .spot{margin-bottom:var(--s-2);}
.empty-block{display:flex;flex-direction:column;align-items:flex-start;gap:var(--s-2);}
.empty-block .spot{margin:0 0 var(--s-1);}

/* On a phone the calendar's head has room for the lenses and the one
   primary action; the hub clock is a desk-sized detail. */
@media(max-width:640px){ .cal-clock{display:none;} }
.lab-acts{display:inline-flex;gap:var(--s-4);align-items:baseline;}

/* The crest's box is 44px; a drawing in its place wants a little more. */
.fixture.empty .fixture-crest{width:64px;height:64px;}
.fixture.empty .fixture-crest .spot{width:64px;height:64px;}

/* ============================================================
   §43  HOME, AS THE PROTOTYPE DREW IT — 10 September 2026

   The fixture is the object: a bigger crest, the competition under
   the venue. On the game-day tile the kick-off is set large, "Game"
   is the kind, and the opponent's mark sits in the corner the way
   it does on the prototype Eóin called the best version.
   ============================================================ */
.day .k{font-size:var(--fs-sm);font-weight:var(--w-emph);color:var(--ink);margin-top:2px;}
.day.is-game .k{color:var(--accent-deep);}
.day-opp{
  position:absolute;right:6px;top:8px;width:34px;height:34px;border-radius:50%;
  border:2px solid var(--them);display:grid;place-items:center;
  font-family:var(--display);font-weight:700;font-size:13px;letter-spacing:.02em;color:var(--them);
}
.day.is-past .day-opp{opacity:.5;}
@media(max-width:640px){ .day-opp{width:28px;height:28px;font-size:11px;top:6px;right:4px;} }


/* ============================================================
   §44  OUTSIDE THE BOX, INSIDE THE RULES — 10 September 2026

   Motion that explains, graphics that carry the match, marks that
   react. Nothing loops, nothing hovers, everything has a cause.
   ============================================================ */

/* the match as a line */
.gd-tl{display:block;width:100%;height:auto;margin:var(--s-2) 0 var(--s-3);font-family:var(--body);}

/* the form guide: a row of marks, oldest first */
.form{display:inline-flex;gap:3px;align-items:center;vertical-align:middle;margin-left:8px;}
.form i{width:9px;height:9px;border-radius:50%;display:inline-block;background:var(--ink-4);}
.form i.W{background:var(--accent);}
.form i.L{background:var(--red);}
.form i.D{background:var(--ink-3);}
.sea-goals .form{margin-left:10px;}

/* the formation drawn */
.form-glyph{display:inline-block;vertical-align:middle;color:var(--ink-2);margin-right:6px;flex:none;}
.gd-door small .form-glyph{color:currentColor;margin-right:2px;vertical-align:-3px;}
.lu-form{vertical-align:middle;flex:none;min-width:5.6em;width:auto;}
/* the toolbar's own rule sizes every svg to its box; the glyph keeps its own */
svg.form-glyph{flex:none;width:34px;height:22px;min-width:34px;max-width:34px;}
.gd-door small svg.form-glyph{width:24px;height:16px;min-width:24px;max-width:24px;}

/* the team sheet's ring: how much of the eleven is picked */
.spine-ring{width:18px;height:18px;display:block;margin-bottom:2px;}
.spine-ring circle{transition:stroke-dashoffset var(--t-slow) var(--out);}

/* the ring says what state a man is in */
.pl-face{position:relative;}
.pl-face.limited{border-style:dashed;border-color:var(--amber);}
.pl-face.susp{border-color:var(--ink-3);filter:saturate(.4);}
.pl-face.susp::after{
  content:"";position:absolute;inset:0;border-radius:50%;
  background:linear-gradient(135deg,transparent 46%,var(--red) 46%,var(--red) 54%,transparent 54%);
  opacity:.9;
}

/* the eye widens for a goal */
#suilEye .pupil{transform-box:fill-box;transform-origin:center;}
#suilEye.goal .pupil{animation:eye-goal 900ms var(--out);}
#suilEye.goal .iris{animation:eye-goal-iris 900ms var(--out);}
@keyframes eye-goal{0%{transform:scale(1)}30%{transform:scale(2.2)}100%{transform:scale(1)}}
@keyframes eye-goal-iris{0%{transform:scale(1)}30%{transform:scale(1.18)}100%{transform:scale(1)}}

/* a screen explains itself once: the line, and a hand-drawn underline */
.section-sub.first{position:relative;animation:sub-settle 9s var(--ease) forwards;}
.section-sub.first::after{
  content:"";position:absolute;left:0;bottom:-4px;height:2px;width:0;border-radius:2px;
  background:var(--accent);animation:sub-draw 700ms var(--out) 300ms forwards;
}
@keyframes sub-draw{to{width:64px;}}
@keyframes sub-settle{0%,75%{opacity:1}100%{opacity:.6}}
.what{display:none;}
@media (prefers-reduced-motion: reduce){
  .section-sub.first,.section-sub.first::after,#suilEye.goal .pupil,#suilEye.goal .iris{animation:none;}
  .section-sub.first::after{width:64px;}
}
:root[data-sun="on"] .section-sub.first{animation:none;}


/* ============================================================
   §45  THE COACH ACTION, CAPTURED — 10 September 2026

   Run the session: one activity in the hand, the clock, the picture,
   the lens set large, and one tap when play stops that asks what
   broke — C, D or E — and where. On the touchline the same chips
   ask which moment. Everything at the 44/56/64 floors, solid paper,
   nothing frosted: this is used standing up in daylight.
   ============================================================ */
body.run-full #sidebar,body.run-full .topbar-mobile,body.run-full .section-head,body.run-full .crumbs,body.run-full #suilEye{display:none !important;}
body.run-full #main{background:var(--bg);}
body.run-full .section{padding:0;max-width:none;}
.run{min-height:100vh;display:flex;flex-direction:column;padding:var(--s-4) var(--s-5) var(--s-8);gap:var(--s-4);max-width:900px;margin:0 auto;}
.run-head{display:flex;align-items:center;gap:var(--s-3);}
.run-title{flex:1;min-width:0;display:flex;flex-direction:column;line-height:1.2;}
.run-title b{font-weight:var(--w-emph);font-size:var(--fs-md);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.run-title span{font-size:var(--fs-sm);color:var(--ink-2);}
.run-session-clock{font-family:var(--display);font-weight:700;font-size:28px;color:var(--ink-2);font-variant-numeric:tabular-nums;min-width:48px;text-align:right;}
.run-strip{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--s-3);align-items:end;padding-bottom:var(--s-3);border-bottom:2px solid var(--line-2);}
.run-where{grid-column:1 / -1;font-size:var(--fs-sm);color:var(--ink-2);font-weight:500;}
.run-name{font-family:var(--display);font-weight:700;font-size:clamp(30px,5vw,44px);line-height:1;letter-spacing:-.01em;}
.run-clock{display:flex;align-items:baseline;gap:6px;font-variant-numeric:tabular-nums;}
.run-clock b{font-family:var(--display);font-weight:800;font-size:clamp(40px,7vw,64px);line-height:1;letter-spacing:-.01em;}
.run-clock span{font-size:var(--fs-base);color:var(--ink-2);}
.run-clock.over b{color:var(--amber);}
.run-body{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:var(--s-5);align-items:start;}
@media(max-width:700px){ .run-body{grid-template-columns:1fr;} }
.run-pic{border-radius:var(--r-md);overflow:hidden;background:var(--surface);box-shadow:inset 0 0 0 2px var(--line-2);}
.run-pic svg,.run-pic img{display:block;width:100%;height:auto;}
.run-text{display:flex;flex-direction:column;gap:var(--s-4);}
.run-k{display:block;font-size:var(--fs-xs);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);font-weight:700;margin-bottom:4px;}
.run-look{font-size:clamp(20px,2.6vw,26px);line-height:1.3;font-weight:var(--w-emph);}
.run-look.muted{color:var(--ink-3);font-weight:500;}
.run-rules{font-size:var(--fs-md);line-height:1.5;color:var(--ink-2);}
.run-coach{font-size:var(--fs-base);color:var(--ink-3);line-height:1.5;padding-top:var(--s-2);border-top:1px solid var(--line);}
.run-bar{display:flex;gap:var(--s-3);align-items:center;flex-wrap:wrap;}
.run-big{
  flex:1;min-width:120px;min-height:64px;padding:0 var(--s-4);border-radius:var(--r-md);
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  font-size:var(--fs-lg);font-weight:var(--w-emph);background:var(--surface);color:var(--ink);
  box-shadow:inset 0 0 0 2px var(--line-2);
}
.run-big:disabled{opacity:.35;}
.run-big.primary{background:var(--accent-deep);color:var(--on-accent);box-shadow:none;}
.run-big.stop{background:var(--ink);color:var(--bg);box-shadow:none;flex:1.4;}
.run-big:active{transform:scale(.985);}
.run-dials{display:flex;align-items:center;gap:var(--s-2);flex-wrap:wrap;}
.run-dials .run-k{margin:0 var(--s-2) 0 0;}
.run-dials .tog{font-size:var(--fs-sm);padding:10px 14px;}
.run-rule{display:inline-flex;gap:6px;align-items:center;flex:1;min-width:220px;}
.run-rule input{flex:1;min-height:44px;}
.run-iv{background:var(--surface);border-radius:var(--r-lg);padding:var(--s-4);box-shadow:inset 0 0 0 2px var(--line-2);display:flex;flex-direction:column;gap:var(--s-3);}
.run-iv-h{display:flex;justify-content:space-between;align-items:baseline;font-weight:var(--w-emph);font-size:var(--fs-md);}
.run-iv-t{font-family:var(--display);font-weight:700;font-size:24px;color:var(--ink-2);font-variant-numeric:tabular-nums;}
.run-sub{font-size:var(--fs-sm);font-weight:var(--w-emph);color:var(--ink-2);margin:2px 0 0;}
.run-chips{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s-2);}
.run-chips.small{display:flex;flex-wrap:wrap;}
.run-chip{
  min-height:64px;padding:8px 12px;border-radius:var(--r-md);text-align:left;
  display:flex;flex-direction:column;gap:1px;background:var(--surface-2);color:var(--ink);
  box-shadow:inset 0 0 0 1px var(--line-2);
}
.run-chips.small .run-chip{flex:1 1 120px;min-height:52px;flex-direction:row;align-items:center;gap:10px;}
.run-chip b{font-family:var(--display);font-weight:800;font-size:26px;line-height:1;}
.run-chip span{font-weight:var(--w-emph);font-size:var(--fs-base);}
.run-chip i{font-style:normal;font-size:var(--fs-xs);color:var(--ink-3);}
.run-chip.on{background:var(--accent-deep);color:var(--on-accent);box-shadow:none;}
.run-chip.on i{color:var(--on-accent);opacity:.8;}
.run-note{width:100%;min-height:48px;font-size:var(--fs-md);}
.run-log{display:flex;flex-direction:column;gap:2px;padding-top:var(--s-2);border-top:1px solid var(--line);}
.run-line{display:flex;gap:10px;align-items:baseline;font-size:var(--fs-base);padding:4px 0;color:var(--ink-2);}
.run-line span{font-family:var(--display);font-weight:700;color:var(--ink-3);font-variant-numeric:tabular-nums;min-width:34px;}
.run-line .run-l{font-family:var(--display);font-weight:800;color:var(--accent-deep);font-size:var(--fs-lg);min-width:28px;}
.run-door{display:flex;flex-direction:column;gap:var(--s-3);}
.run-wall{display:grid;grid-template-columns:repeat(auto-fill,minmax(84px,1fr));gap:var(--s-2);}
.run-face{display:flex;flex-direction:column;align-items:center;gap:3px;padding:6px 2px;border-radius:var(--r-md);background:none;min-height:44px;}
.run-face .gdf-face{width:56px;height:56px;}
.run-face .gdf-name{font-size:var(--fs-sm);}
.run-st{font-size:var(--fs-xs);color:var(--ink-3);}
.run-face.st-limited .gdf-face{border-style:dashed;border-color:var(--amber);}
.run-face.st-limited .run-st{color:var(--amber);font-weight:700;}
.run-face.st-out .gdf-face{filter:grayscale(1);border-color:var(--line-2);}
.run-face.st-out .run-st{color:var(--red);font-weight:700;}

/* the touchline: what I saw, half-time, the sub's cost */
.gd-seen{margin:0 0 var(--s-3);}
.gd-seen.open{background:var(--surface);border-radius:var(--r-md);padding:var(--s-3);box-shadow:inset 0 0 0 1px var(--line-2);display:flex;flex-direction:column;gap:var(--s-2);}
.gd-seen.open .run-chips.small .run-chip{min-height:44px;}
.gd-seen.open .run-chip b{font-size:20px;}
.gd-ev.seen .gd-ev-ico{color:var(--ink-2);}
.gd-ht{margin:0 0 var(--s-5);}
.gd-ht-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:var(--s-3) var(--s-5);margin-bottom:var(--s-3);}
.gd-ht-col b{display:block;font-family:var(--display);font-weight:700;font-size:var(--fs-lg);margin-bottom:2px;}
.gd-ht-points{width:100%;font-size:var(--fs-md);line-height:1.5;}
.gd-cost{display:block;font-size:var(--fs-xs);color:var(--ink-3);margin-top:2px;}
.gdf.like .gdf-face{box-shadow:0 0 0 4px var(--accent-soft);}

/* the model, live — each target a pair of big buttons and a running count */
.gd-measure{margin:0 0 var(--s-5);}
.gd-mrow{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:var(--s-3);align-items:center;padding:8px 0;border-bottom:1px solid var(--line);}
.gd-mwho{display:flex;flex-direction:column;line-height:1.25;min-width:0;}
.gd-mwho b{font-family:var(--display);font-weight:700;font-size:var(--fs-lg);}
.gd-mwho span{font-weight:var(--w-emph);font-size:var(--fs-base);}
.gd-mwho small{font-size:var(--fs-xs);color:var(--ink-3);}
.gd-mnum{display:flex;align-items:baseline;gap:4px;font-variant-numeric:tabular-nums;min-width:96px;justify-content:flex-end;}
.gd-mnum b{font-family:var(--display);font-weight:800;font-size:30px;line-height:1;}
.gd-mnum i{font-style:normal;font-size:var(--fs-xs);color:var(--ink-3);}
.gd-mnum em{font-style:normal;font-family:var(--display);font-weight:700;font-size:var(--fs-md);color:var(--ink-2);margin-left:4px;}
.gd-mnum.on em{color:var(--accent-deep);} .gd-mnum.off em{color:var(--amber);}
.gd-mbtns{display:flex;gap:6px;}
.gd-mbtn{width:56px;height:56px;border-radius:var(--r-md);display:grid;place-items:center;background:var(--surface);box-shadow:inset 0 0 0 2px var(--line-2);color:var(--ink);}
.gd-mbtn.yes{color:var(--accent-deep);} .gd-mbtn.no{color:var(--red);}
.gd-mbtn:active{transform:scale(.96);}
@media(max-width:640px){ .gd-mrow{grid-template-columns:minmax(0,1fr) auto;} .gd-mnum{grid-column:1;justify-content:flex-start;} .gd-mbtns{grid-column:2;grid-row:1 / span 2;} }


/* ============================================================
   §46  SATURDAY INTO TUESDAY — 10 September 2026
   ============================================================ */
.seen-chips{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 var(--s-3);}
.seen-chip{
  display:inline-flex;align-items:center;gap:8px;min-height:40px;padding:6px 12px 6px 10px;
  border-radius:var(--r-capsule);background:var(--surface);box-shadow:inset 0 0 0 1px var(--line-2);
  color:var(--ink);text-align:left;transition:background var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease);
}
.seen-chip b{font-family:var(--display);font-weight:700;font-size:var(--fs-md);color:var(--accent-deep);}
.seen-chip span{font-weight:var(--w-emph);font-size:var(--fs-sm);}
.seen-chip i{font-style:normal;font-size:var(--fs-xs);color:var(--ink-3);font-variant-numeric:tabular-nums;}
.seen-chip.on{background:var(--ink);color:var(--bg);box-shadow:none;}
.seen-chip.on b,.seen-chip.on i{color:var(--bg);opacity:.85;}
.rep-v .seen-chips{margin:0;}
.provoke{
  background:var(--surface);border-radius:var(--r-lg);padding:var(--s-4);margin:var(--s-2) 0 var(--s-5);
  box-shadow:inset 0 0 0 1px var(--line-2);display:flex;flex-direction:column;gap:var(--s-3);
}
.provoke-h{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--s-3);}
.provoke-h b{display:block;font-family:var(--display);font-weight:700;font-size:26px;line-height:1.05;letter-spacing:-.005em;}
.provoke .lead{margin:0;}
.provoke-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:var(--s-3);}
.provoke-card{display:flex;flex-direction:column;gap:6px;}
.provoke-thumb{border-radius:var(--r-sm);overflow:hidden;box-shadow:inset 0 0 0 1px var(--line);background:var(--surface-2);}
.provoke-thumb svg{display:block;width:100%;height:auto;}
.provoke-who{display:flex;flex-direction:column;line-height:1.25;}
.provoke-who b{font-weight:var(--w-emph);font-size:var(--fs-base);}
.provoke-who span{font-size:var(--fs-xs);color:var(--ink-3);}
.provoke-acts{display:flex;gap:4px;flex-wrap:wrap;}
.provoke-foot{display:flex;align-items:center;gap:var(--s-2);flex-wrap:wrap;padding-top:var(--s-2);border-top:1px solid var(--line);}
.provoke-foot .run-k{margin:0 var(--s-2) 0 0;}


/* ============================================================
   §47  THE REST OF THE LIST — 10 September 2026, late
   ============================================================ */
/* put it on the Home Screen, once */
.a2hs{display:flex;align-items:center;gap:var(--s-3);padding:var(--s-3) var(--s-4);margin:0 0 var(--s-5);border-radius:var(--r-md);background:var(--surface);box-shadow:inset 0 0 0 1px var(--line-2);}
.a2hs .spot{margin:0;color:var(--ink-2);}
.a2hs-t{flex:1;min-width:0;display:flex;flex-direction:column;line-height:1.3;}
.a2hs-t b{font-weight:var(--w-emph);}
.a2hs-t span{font-size:var(--fs-sm);color:var(--ink-2);}
/* two video challenges each */
.gd-chal{display:flex;gap:6px;align-items:center;}
.gd-chal-btn{min-height:36px;padding:0 10px;border-radius:var(--r-sm);background:var(--surface);box-shadow:inset 0 0 0 1px var(--line-2);font-size:var(--fs-xs);color:var(--ink-2);display:inline-flex;gap:6px;align-items:center;}
.gd-chal-btn b{font-family:var(--display);font-weight:700;font-size:var(--fs-md);color:var(--ink);}
@media(pointer:coarse){ .gd-chal-btn{min-height:44px;} }
/* the exit ticket */
.held{display:flex;align-items:center;gap:var(--s-3);flex-wrap:wrap;margin:0 0 var(--s-3);}
.held .run-k{margin:0;}
.held-btns{display:flex;gap:6px;}
.last-held{display:flex;gap:8px;align-items:baseline;font-size:var(--fs-sm);color:var(--ink-2);padding:8px 12px;border-radius:var(--r-sm);background:var(--surface-2);margin:0 0 var(--s-3);}
.last-held svg{color:var(--accent-deep);flex:none;position:relative;top:2px;}


/* ============================================================
   §48  TEMPO INTO SÚIL — 11 September 2026
   The ideas from the other-way prototype, in this app's ink: today stood
   in, the read-back, one whistle, the model hearing its own words, and
   where the attention went.
   ============================================================ */
/* today, stood in */
.today{margin:var(--s-5) 0 0;}
.tcard{background:var(--surface);border-radius:var(--r-md);padding:var(--s-4);box-shadow:inset 0 0 0 1px var(--line-2);margin:0 0 var(--s-3);}
.tcard.done{opacity:.78;}
.tcard-k{font-size:var(--fs-xs);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);font-weight:var(--w-emph);display:flex;gap:6px;align-items:center;margin:0 0 4px;}
.tcard-k svg{color:var(--accent-deep);}
.tcard-t{font-family:var(--display);font-weight:700;font-size:var(--fs-xl);letter-spacing:-.01em;line-height:1.1;margin:0 0 6px;text-wrap:balance;}
.tcard-p{margin:0 0 6px;font-size:var(--fs-base);color:var(--ink);max-width:64ch;line-height:1.5;}
.tcard-p.muted{color:var(--ink-2);}
.tcard .row-acts{margin-top:var(--s-2);}
/* the read-back */
.readback{background:var(--accent-soft);border-radius:var(--r-md);padding:var(--s-4);box-shadow:inset 0 0 0 1px var(--accent-line, var(--line-2));margin:0 0 var(--s-3);}
.rb-h{display:flex;flex-direction:column;margin:0 0 var(--s-2);}
.rb-h b{font-family:var(--display);font-weight:700;font-size:var(--fs-xl);letter-spacing:-.01em;line-height:1.1;}
.rb-line{font-size:var(--fs-md);line-height:1.5;margin:0 0 var(--s-3);max-width:64ch;color:var(--ink);}
.rb-log{margin:0 0 var(--s-3);border-top:0;padding-top:0;}
.rb-word{font-style:normal;color:var(--accent-deep);font-weight:var(--w-emph);margin-right:6px;}
.readback .held{margin:0;}
.readback .held .run-k i{font-style:normal;text-transform:none;letter-spacing:0;color:var(--ink-2);font-weight:500;}
/* the model hears its own words */
.heard{display:flex;gap:6px;align-items:center;font-size:var(--fs-sm);color:var(--ink-2);}
.heard svg{color:var(--accent-deep);flex:none;}
.heard b{color:var(--accent-deep);font-family:var(--display);font-weight:700;}
/* where the attention went */
.attn{margin:var(--s-5) 0 var(--s-6);}
.attn-rows{display:grid;gap:6px;max-width:640px;}
.attn-row{display:grid;grid-template-columns:36px minmax(0,1fr) minmax(0,2fr) 30px;gap:10px;align-items:center;font-size:var(--fs-sm);}
.attn-row b{font-family:var(--display);font-weight:700;font-size:var(--fs-md);color:var(--accent-deep);}
.attn-row.none b,.attn-row.none .attn-n{color:var(--ink-3);}
.attn-name{color:var(--ink-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.attn-bar{height:8px;border-radius:999px;background:var(--surface-2);overflow:hidden;}
.attn-bar i{display:block;height:100%;background:var(--accent);border-radius:999px;transition:width var(--t-slow) var(--out);}
.attn-n{font-family:var(--display);font-weight:700;text-align:right;font-variant-numeric:tabular-nums;color:var(--ink);}
/* the whistle */
.whistle-bar{
  position:fixed;left:50%;transform:translateX(-50%);bottom:calc(14px + env(safe-area-inset-bottom));z-index:40;
  display:flex;align-items:center;gap:var(--s-3);
  background:var(--surface);border-radius:999px;padding:6px 6px 6px 18px;
  box-shadow:0 14px 40px -14px rgba(0,0,0,.45),inset 0 0 0 1px var(--line-2);
  width:min(520px,calc(100vw - 32px));
}
.whistle-ctx{flex:1;min-width:0;display:flex;flex-direction:column;line-height:1.2;}
.whistle-ctx b{font-family:var(--display);font-weight:700;font-size:var(--fs-md);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--ink);}
.whistle-ctx span{font-size:var(--fs-xs);color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.whistle{
  position:relative;isolation:isolate;overflow:hidden;flex:none;width:64px;height:64px;border-radius:50%;
  background:var(--accent);color:var(--on-accent);display:grid;place-items:center;
  touch-action:none;-webkit-user-select:none;user-select:none;
  transition:transform var(--t-fast) var(--out),background var(--t-fast) var(--out);
}
.whistle:active{transform:scale(.94);}
.whistle.armed{background:var(--ink);color:var(--bg);}
.whistle .fill{position:absolute;inset:0;z-index:0;background:rgba(255,255,255,.28);transform:scaleY(0);transform-origin:bottom center;}
.whistle.holding .fill{transform:scaleY(1);transition:transform 600ms linear;}
.whistle svg{position:relative;z-index:1;width:30px;height:30px;}
body.has-whistle #content{padding-bottom:120px;}
@media(prefers-reduced-motion:reduce){ .whistle{transition:none;} .whistle.holding .fill{transition:none;} }

/* the season reads the process: countable hours, what held, the film */
.sea-wk .sea-h{font-style:normal;font-family:var(--display);font-weight:700;font-size:var(--fs-sm);color:var(--ink-3);display:block;margin-top:2px;font-variant-numeric:tabular-nums;}
.sea-wk .sea-h.over{color:var(--red);}
.sea-wk .sea-flag{font-style:normal;font-size:var(--fs-xs);color:var(--amber);display:block;line-height:1.2;}
.held-wrap{margin:0 0 var(--s-6);}
.held-row{display:flex;align-items:center;gap:var(--s-3);flex-wrap:wrap;margin:0 0 var(--s-3);}
.held-row .run-k{margin:0;min-width:150px;}
.held-marks{display:flex;gap:6px;flex-wrap:wrap;}
.held-mark{display:flex;flex-direction:column;align-items:center;gap:3px;padding:4px 2px;min-width:38px;border-radius:var(--r-sm);}
.held-mark:hover{background:var(--surface-2);}
.held-mark i{display:block;width:14px;height:14px;border-radius:50%;box-shadow:inset 0 0 0 2px var(--line-2);}
.held-mark.yes i{background:var(--accent);box-shadow:none;}
.held-mark.partly i{background:linear-gradient(90deg,var(--accent) 50%,transparent 50%);box-shadow:inset 0 0 0 2px var(--accent);}
.held-mark.no i{box-shadow:inset 0 0 0 2px var(--ink-3);}
.held-mark span{font-size:var(--fs-xs);color:var(--ink-3);white-space:nowrap;}
.held-sum{font-size:var(--fs-sm);color:var(--ink-2);}
.held-model{display:flex;gap:6px;flex-wrap:wrap;}
.held-t{display:inline-flex;align-items:baseline;gap:5px;padding:6px 10px;border-radius:999px;background:var(--surface);box-shadow:inset 0 0 0 1px var(--line-2);font-family:var(--display);font-weight:700;font-size:var(--fs-md);color:var(--ink-2);}
.held-t b{color:var(--ink-3);font-size:var(--fs-sm);}
.held-t i{font-style:normal;font-family:var(--body);font-weight:500;font-size:var(--fs-xs);color:var(--ink-3);}
.held-t.ok{color:var(--accent-deep);}
.gd-video{display:flex;align-items:center;gap:8px;margin:0 0 var(--s-3);color:var(--ink-3);}
.gd-video input{flex:1;min-height:40px;font-size:var(--fs-sm);}

/* the deck as a file: one quiet strip under the session title */
.deck-ready{display:flex;align-items:center;gap:var(--s-3);flex-wrap:wrap;margin:var(--s-3) 0 0;padding:10px 14px;border-radius:var(--r-md);background:var(--surface);box-shadow:inset 0 0 0 1px var(--line-2);font-size:var(--fs-sm);color:var(--ink-2);}
.deck-ready svg{color:var(--accent-deep);flex:none;}
.deck-name{flex:1;min-width:0;display:flex;flex-direction:column;line-height:1.25;}
.deck-name b{color:var(--ink);font-weight:var(--w-emph);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.deck-ready.busy{flex-direction:column;align-items:stretch;gap:8px;}
.deck-bar{display:block;height:6px;border-radius:999px;background:var(--surface-2);overflow:hidden;}
.deck-bar i{display:block;height:100%;width:0;background:var(--accent);border-radius:999px;transition:width var(--t-base) var(--out);}
.deck-ready.err{color:var(--red);}

/* Home, every pixel: the fixture and its three steps are one object; Today
   stands apart from them; the five days stay five on an iPad. */
.section.home .fixture{padding-bottom:var(--s-3);}
.section.home .spine{padding-top:0;}
.section.home .today{margin-top:var(--s-7);}
.section.home .days + .needs{margin-top:var(--s-7);}
@media(min-width:700px) and (max-width:1000px){
  .section.home .days{grid-template-columns:repeat(5,minmax(0,1fr));}
  .section.home .day p{display:none;}
}


/* ============================================================
   §49  DESIGN_FEEL — 11 September 2026
   A well-made instrument that recedes. Sentence case, no dot strings,
   no arrows, no hover lifts, no sheens, one ink on the title, boxes
   only for things you pick up, the eye only where it reacts.
   ============================================================ */
/* labels are sentence case, secondary ink, body size */
.run-k,.tcard-k,.home-list .call-dow{text-transform:none;letter-spacing:0;font-size:var(--fs-sm);font-weight:var(--w-emph);color:var(--ink-2);}
.tcard-k{display:block;margin:0 0 4px;}
/* the title of the day is one ink */
.section.home h1{font-weight:800;}
.section.home h1 .dt{color:inherit;font-weight:700;}
.section.home h1 .muted{color:inherit;}
/* today is a ruled block, not a box; the read-back keeps its tint because it is a question */
.tcard,.tcard.done{background:none;box-shadow:none;border-radius:0;padding:var(--s-4) 0;margin:0;border-top:1px solid var(--line);}
.today .lab.rule + .tcard{border-top:0;padding-top:0;}
.tcard.done{opacity:1;}
.tcard.done .tcard-t{color:var(--ink-2);}
.tcard-p{color:var(--ink-2);}
/* the day says what it is; the note is one line */
.section.home .day p{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;overflow:hidden;}
@media(min-width:700px) and (max-width:1000px){ .section.home .day p{display:none;} }
/* nothing lifts under a pointer that is only passing */
.card.hoverable:hover{box-shadow:none;transform:none;background:var(--surface);}
.needs-row:hover,.next-session:hover{padding-left:0;}
.day:hover{background:none;}
.held-mark:hover,.set-col:hover,.mw-row:not(.on):hover{background:none;}
.sea-day:not(.is-game):not(.is-today):hover{box-shadow:none;}
.sea-day.is-game:hover{box-shadow:inset 0 0 0 1px var(--line-2);}
.sea-day.is-today:hover{box-shadow:inset 0 0 0 2px var(--accent);}
.needs-go{display:none;}
/* no sheens */
#sidebar::before,.toast::before,.lg::after{display:none;}
/* the eye reacts on the touchline and is not drawn anywhere else */
body:not([data-tab="gameday"]) #suilEye{display:none;}
/* the remaining eyebrows: sentence case, no tracking */
.u-label,.eyebrow,.glance-label,.dz-ptitle{text-transform:none;letter-spacing:0;font-size:var(--fs-sm);font-weight:var(--w-emph);color:var(--ink-2);}


/* ============================================================
   §50  THE COLD REVIEW — 13 September 2026
   ============================================================ */
/* a game whose clock ran before its day: the coach decides */
.gd-stale{display:flex;align-items:center;gap:var(--s-4);flex-wrap:wrap;padding:var(--s-3) var(--s-4);margin:0 0 var(--s-3);border-radius:var(--r-md);background:var(--amber-soft);box-shadow:inset 0 0 0 1px var(--line-2);}
.gd-stale-t{flex:1;min-width:240px;display:flex;flex-direction:column;gap:2px;line-height:1.4;}
.gd-stale-t b{font-weight:var(--w-emph);}
.gd-stale-t span{font-size:var(--fs-sm);color:var(--ink-2);}
/* a hold-to-confirm in the shape of a button, for things that must not be a tap */
.gd-hold{position:relative;isolation:isolate;overflow:hidden;display:inline-flex;flex-direction:column;align-items:center;justify-content:center;gap:0;line-height:1.1;touch-action:none;-webkit-user-select:none;user-select:none;}
.gd-hold .lbl,.gd-hold .hint{position:relative;z-index:1;}
.gd-hold .hint{font-size:10px;font-weight:500;opacity:.75;}
.gd-hold .fill{position:absolute;left:0;top:0;bottom:0;width:100%;z-index:0;transform:scaleX(0);transform-origin:left center;background:rgba(0,0,0,.14);}
.gd-hold.holding .fill{transform:scaleX(1);transition:transform 600ms linear;}
.gd-reset{display:flex;align-items:center;gap:var(--s-3);justify-content:flex-end;margin:var(--s-4) 0 0;}
/* the command bar sits on the viewport, and the page beneath it holds still */
#cmdRoot .cmd{position:fixed;}
body.cmd-open #main{overflow:hidden;}
/* a filter that is on looks on */
.pill.active{background:var(--ink);color:var(--bg);border-color:transparent;}
/* the calendar's head keeps one height across its lenses; a subtitle keeps its room after it has been read */
.section-head{min-height:56px;}
.section-sub.ghost{visibility:hidden;}
/* a face shows its initials until the photo arrives */
.pl-face{position:relative;}
.pl-face img{position:absolute;inset:0;}
/* the challenges say what they are */
.gd-chal{display:flex;gap:6px;align-items:center;flex-wrap:wrap;}
.gd-chal-l{font-size:var(--fs-xs);color:var(--ink-3);margin-right:2px;}
/* the rail's doors are links */
nav a.nav-btn{text-decoration:none;}
/* a screen's actions are one group that wraps as a group, right-aligned, and never splits around the title */
.section-acts{display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:8px;margin-left:auto;max-width:100%;}
.sync.quiet::before{display:none;}
/* who else is on the game */
.gd-live{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-xs);color:var(--ink-2);margin-left:10px;}
.gd-live i{width:7px;height:7px;border-radius:50%;background:var(--accent);box-shadow:0 0 0 3px var(--accent-soft);}
/* the touchline listens */
.whistle-mic{flex:none;width:44px;height:44px;border-radius:50%;display:grid;place-items:center;color:var(--ink-2);box-shadow:inset 0 0 0 1px var(--line-2);background:var(--surface);transition:background var(--t-fast) var(--out),color var(--t-fast) var(--out);}
.whistle-mic.on{background:var(--accent-deep);color:var(--on-accent);box-shadow:none;animation:mic-pulse 1.2s ease-in-out infinite;}
@keyframes mic-pulse{0%,100%{box-shadow:0 0 0 0 rgba(var(--accent-rgb),.38)}50%{box-shadow:0 0 0 8px rgba(var(--accent-rgb),0)}}
@media (prefers-reduced-motion: reduce){ .whistle-mic.on{animation:none;} }


/* ============================================================
   §51  THE STAGE — 13 September 2026
   The pitch is the interface. The eleven on the grass, on Home.
   ============================================================ */
.stage{margin:0 0 var(--s-6);border-radius:var(--r-lg);overflow:hidden;background:var(--surface);box-shadow:var(--sh-lift),inset 0 0 0 1px var(--line);}
.stage-head{display:flex;align-items:center;gap:var(--s-4);padding:var(--s-4) var(--s-5);}
.stage-crest{flex:none;width:64px;height:64px;display:grid;place-items:center;}
.stage-crest svg,.stage-crest img{width:64px;height:64px;}
.stage-who{flex:1;min-width:0;}
.stage-line{font-family:var(--display);font-weight:800;font-size:clamp(28px,4vw,44px);line-height:1;letter-spacing:-.01em;color:var(--ink);text-wrap:balance;}
.stage-line i{font-style:normal;font-weight:600;color:var(--ink-3);margin:0 .12em;}
.stage-meta{margin-top:6px;font-size:var(--fs-base);color:var(--ink-2);max-width:72ch;line-height:1.45;}
.stage-count{flex:none;text-align:right;font-family:var(--display);font-weight:800;line-height:.9;letter-spacing:-.02em;color:var(--accent-deep);display:flex;flex-direction:column;align-items:flex-end;}
.stage-count b{font-size:clamp(40px,6vw,72px);font-weight:800;font-variant-numeric:tabular-nums;}
.stage-count span{font-family:var(--body);font-size:var(--fs-sm);font-weight:var(--w-emph);color:var(--ink-3);letter-spacing:0;margin-top:2px;}
.stage-pitch{display:block;width:100%;padding:0;margin:0;border:0;background:none;cursor:pointer;}
.stage-svg{display:block;width:100%;height:auto;}
.stage-turf{fill:var(--turf);}
.stage-svg .lu-slot circle{stroke:rgba(255,255,255,.9) !important;fill:rgba(255,255,255,.10) !important;stroke-dasharray:6 5;}
.stage-svg .lu-slot .lu-slot-t.plus{display:none;}
.stage-svg .lu-slot .lu-slot-t.gk{fill:#fff !important;opacity:.9;}
.stage-svg .lu-tok{cursor:pointer;}
.stage-svg .lu-tok text{stroke:none !important;}
.stage-svg .lu-tok .lu-name,.stage-svg .lu-tok text:last-child{fill:#fff !important;paint-order:stroke;stroke:rgba(0,0,0,.45) !important;stroke-width:3px;stroke-linejoin:round;}
.stage-pitch:focus-visible{outline:3px solid var(--accent);outline-offset:-3px;}
.stage-foot{display:flex;align-items:center;justify-content:space-between;gap:var(--s-3);flex-wrap:wrap;padding:var(--s-3) var(--s-5);border-top:1px solid var(--line);}
.stage-eleven{font-size:var(--fs-base);color:var(--ink-2);}
.stage-eleven b{color:var(--ink);font-weight:var(--w-emph);}
.stage-steps{display:flex;gap:6px;flex-wrap:wrap;}
.stage-step{display:inline-flex;align-items:baseline;gap:6px;min-height:40px;padding:6px 14px;border-radius:999px;font-size:var(--fs-sm);font-weight:var(--w-emph);line-height:1.15;color:var(--ink-2);box-shadow:inset 0 0 0 1px var(--line-2);background:var(--surface);}
.stage-step b{font-weight:var(--w-emph);color:var(--ink);}
.stage-step span{font-size:var(--fs-xs);color:var(--ink-3);font-weight:500;}
.stage-step.on{box-shadow:inset 0 0 0 2px var(--accent);}
.stage-step.on b{color:var(--accent-deep);}
.stage-step.later{opacity:.6;}
@media(max-width:640px){
  .stage-head{flex-wrap:wrap;}
  .stage-count{width:100%;align-items:flex-start;flex-direction:row;gap:8px;align-items:baseline;}
}
/* Matchday runs on the same grass */
.gd-stage{border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--sh-lift),inset 0 0 0 1px var(--line);margin:0 0 var(--s-4);position:relative;background:var(--surface);}
.gd-stage.armed .stage-svg{outline:3px solid var(--accent);outline-offset:-3px;border-radius:4px;}
.gd-stage .stage-svg .lu-tok.sel .lu-ring{stroke:#fff;stroke-width:6;}
.gd-stage .stage-svg .lu-tok.sel .lu-shadow{opacity:.5;}
.gd-stage-empty{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);background:var(--surface);padding:10px 16px;border-radius:999px;box-shadow:var(--sh-lift);margin:0;}
@media(pointer:coarse){ .gd-stage .stage-svg .lu-tok{cursor:pointer;} }
/* the season as a strip of pictures: phases in colour, games as crests, sessions as their drawings */
.sea-band{--band:var(--surface-3);}
.sea-band.is-now{--band:var(--accent);}
.sea-swatch{display:inline-block;width:12px;height:12px;border-radius:4px;background:var(--band);margin-right:8px;vertical-align:-1px;}
.sea-band .sea-week{border-left:3px solid var(--band);padding-left:var(--s-3);}
.sea-day{min-height:96px;align-items:stretch;}
.sea-crest{display:grid;place-items:center;width:36px;height:36px;border-radius:50%;background:var(--surface);box-shadow:inset 0 0 0 2px var(--accent);font-family:var(--display);font-weight:700;font-size:13px;color:var(--accent-deep);margin:4px 0 2px;overflow:hidden;}
.sea-crest.away{box-shadow:inset 0 0 0 2px var(--ink-3);color:var(--ink-2);}
.sea-crest img{width:100%;height:100%;object-fit:contain;}
.sea-day.has-res.W .sea-crest{box-shadow:inset 0 0 0 3px var(--accent);}
.sea-day.has-res.L .sea-crest{box-shadow:inset 0 0 0 2px var(--red);color:var(--red);}
.sea-res{font-size:var(--fs-xs);font-weight:var(--w-emph);}
.sea-res.W{color:var(--accent-deep);} .sea-res.L{color:var(--red);} .sea-res.D{color:var(--ink-2);}
.sea-day.has-thumb .sea-what{margin-top:auto;}


/* ============================================================
   §52  ROOM TO BREATHE — 13 September 2026
   Bigger names, more air, the display face doing the talking.
   ============================================================ */
.section h1{font-size:clamp(34px,3.6vw,44px);font-weight:800;letter-spacing:-.012em;}
.section.home h1{font-size:clamp(38px,4.8vw,68px);}
@media(min-width:1100px){ .section{padding:40px 48px 64px;max-width:1240px;} }
.lab.rule{padding-bottom:10px;margin-bottom:var(--s-4);}
.lab.rule > span:first-child{font-size:var(--fs-sm);font-weight:var(--w-emph);color:var(--ink-2);letter-spacing:0;}
.day .d{font-size:clamp(22px,2.4vw,30px);}
.tcard-t{font-size:clamp(24px,2.6vw,32px);}
.modes{margin-bottom:var(--s-6);}
.mode-l{font-size:var(--fs-md);}
/* the rail speaks a little louder */
.brand-title{font-size:26px;}
nav .nav-btn{font-size:17px;}
/* the five days carry pictures */
.day-pic{display:grid;place-items:center;height:72px;margin:6px 0 8px;border-radius:8px;overflow:hidden;background:var(--surface-2);}
.day-pic svg{display:block;width:100%;height:100%;}
.day-pic.faint{color:var(--ink-4);opacity:.5;}
.day-pic.faint svg{width:70%;height:70%;}
.day-pic.crest{background:transparent;}
.day-pic.crest img,.day-pic.crest .day-opp{width:52px;height:52px;border-radius:50%;}
.day-pic.crest img{object-fit:contain;background:var(--surface);box-shadow:inset 0 0 0 2px var(--accent);}
.day-pic.crest .day-opp{position:static;margin:0;font-size:16px;border-width:2.5px;border-color:var(--accent);color:var(--accent-deep);}
.day.is-empty .day-pic{display:none;}

/* ------------------------------------------------------------------
   §50 THE SESSION, STEP BY STEP (19 Sep 2026). The six parts of the
   sheet as a rail, one open at a time; the words the model owns as
   chips beside every field that used to want them typed.
   ------------------------------------------------------------------ */
.ses-steps{display:flex;align-items:stretch;gap:0;list-style:none;margin:0;padding:0 var(--s-5);border-bottom:1px solid var(--line);overflow-x:auto;scrollbar-width:none;background:var(--surface);}
.ses-steps::-webkit-scrollbar{display:none;}
.ses-step{flex:1 1 0;min-width:112px;display:flex;}
.ses-step button{display:flex;gap:8px;align-items:flex-start;width:100%;text-align:left;padding:12px 12px 10px 0;background:none;border:0;border-bottom:2px solid transparent;color:var(--ink-3);font:inherit;cursor:pointer;min-width:0;}
.ses-step.now button{color:var(--ink);border-bottom-color:var(--accent);}
.ses-step.done button{color:var(--ink-2);}
.ses-n{flex:none;width:22px;height:22px;border-radius:50%;box-shadow:inset 0 0 0 1.5px var(--line-2);font-family:var(--display);font-weight:700;font-size:var(--fs-sm);display:flex;align-items:center;justify-content:center;margin-top:1px;}
.ses-step.done .ses-n{background:var(--accent-deep);color:var(--on-accent);box-shadow:none;}
.ses-step.now .ses-n{box-shadow:inset 0 0 0 2px var(--accent);color:var(--accent-deep);background:transparent;}
.ses-t{display:flex;flex-direction:column;min-width:0;line-height:1.3;}
.ses-t b{font-weight:var(--w-emph);font-size:var(--fs-sm);}
.ses-t i{font-style:normal;font-size:var(--fs-xs);color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.ses-mode{flex:none;display:flex;align-items:center;padding-left:var(--s-2);}
/* The foot is fixed to the screen, like the whistle bar, so Next never has
   to be scrolled to on a long step. `body.ses-stepping` gives the content
   room under it. */
.ses-foot{
  position:fixed;left:50%;transform:translateX(-50%);
  bottom:calc(14px + env(safe-area-inset-bottom));z-index:39;
  display:flex;align-items:center;gap:var(--s-3);
  padding:6px 6px 6px 10px;border-radius:var(--r-capsule);
  background:var(--surface);
  box-shadow:0 14px 40px -14px rgba(0,0,0,.42),inset 0 0 0 1px var(--line-2);
  width:min(560px,calc(100vw - 32px));
}
body.ses-stepping #content{padding-bottom:104px;}
body.has-whistle .ses-foot{display:none;}   /* the grass owns the bar */
.ses-foot .ses-count{font-size:var(--fs-sm);color:var(--ink-3);margin:0 auto;font-variant-numeric:tabular-nums;white-space:nowrap;}
.ses-foot .ses-count b{color:var(--ink);font-weight:var(--w-emph);}
.ses-foot .btn{white-space:nowrap;}
.ses-prev{min-width:44px;}
.ses-prev:disabled{opacity:.3;}
.ses-prev span:empty{display:none;}
@media (max-width:560px){ .ses-prev span{display:none;} }

/* A step arrives from the side it came from, so moving between them reads
   as one document sliding rather than a page replaced. */
.ses-body.fwd{animation:sesIn 260ms cubic-bezier(0.32,0.72,0,1) both;}
.ses-body.rev{animation:sesInRev 260ms cubic-bezier(0.32,0.72,0,1) both;}
@keyframes sesIn{from{opacity:0;transform:translateX(18px);}to{opacity:1;transform:none;}}
@keyframes sesInRev{from{opacity:0;transform:translateX(-18px);}to{opacity:1;transform:none;}}
@media (prefers-reduced-motion:reduce){ .ses-body.fwd,.ses-body.rev{animation:none;} }

/* Added today, folded: a line you open, not a gate you pass. */
.sheet-sec.fold{padding-top:var(--s-3);padding-bottom:var(--s-3);}
.sheet-sec.fold.open{padding-bottom:var(--s-5);}
.fold-head{display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:none;border:0;padding:6px 0;cursor:pointer;color:var(--ink-2);font:inherit;font-size:var(--fs-sm);}
.fold-head:hover{color:var(--ink);}
.fold-head svg{color:var(--ink-3);flex:none;}
.fold-head span{font-weight:var(--w-emph);}
.fold-n{font-style:normal;font-size:var(--fs-xs);font-weight:var(--w-emph);color:var(--on-accent);background:var(--accent-deep);border-radius:999px;padding:1px 7px;}
.fold-hint{font-style:normal;color:var(--ink-3);font-size:var(--fs-xs);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
@media (max-width:640px){ .fold-hint{display:none;} }
.wbank{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:8px;}
.wbank.inline{display:inline-flex;margin:0;}
.wbank.open{padding:8px 10px;background:var(--surface-2);border-radius:var(--r-sm);gap:8px;}
.wbank-g{display:flex;flex-wrap:wrap;gap:6px;align-items:center;width:100%;}
.wbank-k{font-size:var(--fs-xs);color:var(--ink-3);margin-right:2px;}
.wchip{display:inline-flex;align-items:center;gap:4px;font-size:var(--fs-sm);font-weight:500;padding:4px 10px;border-radius:var(--r-capsule);background:var(--surface);box-shadow:inset 0 0 0 1px var(--line-2);color:var(--ink-2);font-family:inherit;cursor:pointer;line-height:1.3;max-width:100%;text-align:left;}
.wchip:hover{color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink-3);}
.wchip.on{background:var(--ink);color:var(--bg);box-shadow:none;}
.wchip.on svg{opacity:.7;}
.wchip.more{color:var(--accent-deep);box-shadow:none;background:transparent;padding-left:4px;padding-right:4px;}
.xw-row{display:flex;flex-wrap:wrap;gap:6px;align-items:center;}
.xw-row input{flex:1 1 140px;min-width:120px;width:auto;}
@media (pointer:coarse){ .wchip{padding:7px 12px;} .ses-step button{padding-top:14px;padding-bottom:12px;} }
@media (max-width:640px){ .ses-steps{padding:0 var(--s-4);} .ses-t i{display:none;} .ses-step{flex:none;min-width:auto;} .ses-step button{padding-right:14px;} .ses-t b{white-space:nowrap;} .ses-mode{position:sticky;right:0;background:var(--surface);box-shadow:-12px 0 12px -6px var(--surface);} }

/* ------------------------------------------------------------------
   §51 THE PROBLEM, FIRST (21 Sep). The session starts from what it is
   trying to solve, and from what has already been run against it.
   ------------------------------------------------------------------ */
.prob-row{display:flex;gap:6px;flex-wrap:wrap;align-items:center;}
.prob-row.wrap{margin-top:6px;}
.prob-label{font-size:var(--fs-xs);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);font-weight:var(--w-emph);margin:var(--s-4) 0 2px;}
.prob-detail{font-size:var(--fs-base);color:var(--ink-2);line-height:1.5;margin:10px 0 0;max-width:70ch;}
.prob-id{margin-top:var(--s-4);padding:12px 14px;background:var(--surface-2);border-radius:var(--r-sm);}
.prob-id-t{font-size:var(--fs-lg);font-weight:700;letter-spacing:-.015em;}
.prob-id-s{font-size:var(--fs-sm);color:var(--ink-2);margin-top:3px;}
.prob-id .meta{margin-top:4px;}

/* Already run against this: the fast path. A picture, a line, one button. */
.like{margin-top:var(--s-5);}
.like-card{
  display:flex;align-items:center;gap:var(--s-3);
  padding:10px 12px;border-radius:var(--r-md);background:var(--surface);
  box-shadow:inset 0 0 0 1px var(--line-2);margin:0 0 8px;
}
.like-thumbs{display:flex;gap:3px;flex:none;}
.like-th{display:block;width:58px;border-radius:var(--r-xs);overflow:hidden;background:var(--surface-2);}
.like-th img{width:100%;display:block;}
.like-th.empty{display:flex;align-items:center;justify-content:center;height:40px;opacity:.5;}
.like-body{display:flex;flex-direction:column;min-width:0;flex:1;gap:2px;}
.like-body b{font-size:var(--fs-base);font-weight:var(--w-emph);line-height:1.3;overflow:hidden;text-overflow:ellipsis;}
.like-meta{font-size:var(--fs-sm);color:var(--ink-3);}
.like-held{font-size:var(--fs-xs);font-weight:var(--w-emph);align-self:flex-start;padding:1px 8px;border-radius:999px;background:var(--surface-2);color:var(--ink-2);}
.like-held.yes{background:var(--accent-soft);color:var(--accent-deep);}
.like-held.no{background:var(--red-soft);color:var(--red);}
.like-card .btn{flex:none;}
@media (max-width:640px){
  .like-card{flex-wrap:wrap;}
  .like-thumbs .like-th:nth-child(n+3){display:none;}
  .like-card .btn{width:100%;}
}
