/* The training app shell. */
.shell{display:grid;grid-template-columns:76px 1fr;min-height:100vh}

/* ------------------------------------------------------------------ rail */
.rail{
  background:linear-gradient(180deg,#101724,#0a0e15);border-right:1px solid var(--line);
  display:flex;flex-direction:column;align-items:center;gap:8px;padding:16px 0;position:sticky;top:0;height:100vh;
}
.rail .logo{width:34px;height:34px;border-radius:50%;background:var(--hot);box-shadow:0 0 18px rgba(255,90,31,.55);margin-bottom:14px}
.rail button{
  width:48px;height:48px;border-radius:12px;display:grid;place-content:center;
  font-size:19px;color:var(--dim);transition:.14s;position:relative;
}
.rail button:hover{background:#18212f;color:var(--ink)}
.rail button.on{background:rgba(255,90,31,.15);color:var(--hot)}
.rail button.on::before{content:"";position:absolute;left:-16px;top:12px;bottom:12px;width:3px;border-radius:2px;background:var(--hot)}
.rail .spacer{flex:1}
.rail .tip{
  position:absolute;left:60px;background:#1b2534;border:1px solid var(--line);
  padding:6px 11px;border-radius:8px;font-size:12px;white-space:nowrap;opacity:0;
  pointer-events:none;transition:.14s;z-index:50;
}
.rail button:hover .tip{opacity:1}

/* ------------------------------------------------------------------ views */
.view{display:none;padding:22px;max-width:1400px;margin:0 auto;width:100%}
.view.on{display:block}
.vhead{display:flex;align-items:flex-end;gap:14px;margin-bottom:20px;flex-wrap:wrap}
.vhead h1{font:800 28px/1.1 var(--mono);letter-spacing:-1.2px}
.vhead p{color:var(--mute);font-size:14px}
.vhead .right{margin-left:auto;display:flex;gap:9px}

/* --------------------------------------------------------------- dashboard */
.hero{
  display:grid;grid-template-columns:auto 1fr;gap:26px;align-items:center;
  background:radial-gradient(circle at 12% 30%,#1a2436,#0c1018);
  border:1px solid var(--line);border-radius:18px;padding:26px;margin-bottom:18px;
}
@media(max-width:760px){.hero{grid-template-columns:1fr;text-align:center;justify-items:center}}
.hero h2{font:800 25px/1.2 var(--mono);letter-spacing:-1px;margin-bottom:7px}
.hero p{color:var(--mute);max-width:52ch;margin-bottom:15px}
.hero .cta{display:flex;gap:10px;flex-wrap:wrap}
.dash-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:14px}

/* ------------------------------------------------------------------ train */
.train-grid{display:grid;grid-template-columns:1fr 330px;gap:16px}
@media(max-width:1100px){.train-grid{grid-template-columns:1fr}}
.stage{position:relative;background:#000;border:1px solid var(--line);border-radius:var(--r);overflow:hidden;aspect-ratio:4/3}
.stage video,.stage canvas{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.stage video{transform:scaleX(-1)}
.gate{position:absolute;inset:0;display:grid;place-content:center;justify-items:center;gap:15px;text-align:center;padding:28px;background:radial-gradient(circle at 50% 38%,#141d2c,#05070b)}
.gate h2{font:800 24px/1.15 var(--mono);letter-spacing:-.9px;max-width:16ch}
.gate p{color:var(--mute);max-width:40ch;font-size:13.5px}
.gate.hide{display:none}

.hud{position:absolute;top:0;left:0;right:0;display:flex;gap:9px;padding:13px;pointer-events:none;flex-wrap:wrap}
.tile{background:rgba(8,11,17,.84);backdrop-filter:blur(10px);border:1px solid var(--line);border-radius:10px;padding:7px 13px;min-width:76px}
.tile b{display:block;font:800 23px/1 var(--mono);letter-spacing:-1px}
.tile small{display:block;font:600 9px/1 var(--mono);letter-spacing:1.2px;text-transform:uppercase;color:var(--mute);margin-top:5px}
.tile.hot b{color:var(--hot)}

.pop{position:absolute;left:50%;top:40%;transform:translate(-50%,-50%) scale(.7);font:800 84px/1 var(--mono);letter-spacing:-5px;opacity:0;pointer-events:none;text-shadow:0 0 40px currentColor}
.pop.go{animation:pop 1s ease-out}
@keyframes pop{15%{opacity:1;transform:translate(-50%,-50%) scale(1.06)}75%{opacity:1;transform:translate(-50%,-50%) scale(1)}100%{opacity:0;transform:translate(-50%,-58%) scale(1)}}

/* the little companion watching from the corner of the stage */
.watcher{position:absolute;right:14px;bottom:14px;width:104px;pointer-events:none;filter:drop-shadow(0 8px 20px rgba(0,0,0,.6))}

/* ------------------------------------------------- livestream comment feed */
.feed{
  position:absolute;left:0;bottom:0;width:min(60%,460px);padding:14px;
  display:flex;flex-direction:column;justify-content:flex-end;gap:7px;
  max-height:74%;pointer-events:none;
  -webkit-mask-image:linear-gradient(to top,#000 74%,transparent);
  mask-image:linear-gradient(to top,#000 74%,transparent);
}
.msg{
  display:flex;align-items:flex-start;gap:9px;
  background:rgba(10,14,21,.8);backdrop-filter:blur(8px);
  border:1px solid var(--line);border-left:3px solid var(--dim);
  border-radius:10px;padding:8px 11px;font-size:13.5px;line-height:1.45;
  animation:slide .4s cubic-bezier(.2,.9,.3,1.2);
}
@keyframes slide{from{opacity:0;transform:translateX(-26px)}to{opacity:1;transform:none}}
.msg .who{font:700 10px/1.4 var(--mono);letter-spacing:.6px;text-transform:uppercase;color:var(--mute);flex:none}
.msg.great{border-left-color:var(--good)}
.msg.good{border-left-color:var(--cool)}
.msg.mid{border-left-color:var(--hot)}
.msg.poor,.msg.warn{border-left-color:var(--bad)}
.msg.mark,.msg.streak{border-left-color:var(--grape);background:rgba(157,107,255,.1)}
.msg.coach{border-left-color:var(--hot);background:rgba(255,90,31,.1);font-size:14px}
.msg.you{border-left-color:var(--grape)}

/* ------------------------------------------------ transcript dock (bottom right) */
.dock{
  position:fixed;right:18px;bottom:18px;width:318px;z-index:90;
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:0 20px 60px rgba(0,0,0,.6);overflow:hidden;transition:.25s;
}
.dock.min{transform:translateY(calc(100% - 44px))}
.dock header{
  display:flex;align-items:center;gap:9px;padding:12px 14px;cursor:pointer;
  background:var(--panel2);border-bottom:1px solid var(--line);
}
.dock header b{font:700 10px/1 var(--mono);letter-spacing:1.4px;text-transform:uppercase;flex:1}
.dock header .dot{width:7px;height:7px;border-radius:50%;background:var(--good);box-shadow:0 0 9px var(--good);animation:pulse 1.7s infinite}
@keyframes pulse{50%{opacity:.35}}
.dock .lines{max-height:230px;overflow:auto;padding:11px}
.tline{padding:8px 0;border-bottom:1px solid #151d29;font-size:13px;line-height:1.5}
.tline:last-child{border-bottom:0}
.tline .t{font:600 9px/1 var(--mono);color:var(--dim);letter-spacing:.8px;display:block;margin-bottom:4px}
.tline.you .t{color:var(--grape)}
.tline.coach .t{color:var(--hot)}
.dock footer{padding:10px 12px;border-top:1px solid var(--line);font:600 10px/1 var(--mono);color:var(--dim);letter-spacing:.7px;text-align:center}

/* ------------------------------------------------------------------ picker */
.pick{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px}
.pick button{
  background:var(--panel2);border:2px solid var(--line);border-radius:var(--r);
  padding:16px 12px;display:grid;justify-items:center;gap:7px;transition:.16s;
}
.pick button:hover{border-color:#31405a;transform:translateY(-3px)}
.pick button.on{border-color:var(--hot);background:rgba(255,90,31,.09);box-shadow:0 8px 26px rgba(255,90,31,.2)}
.pick b{font:700 14px/1 var(--mono)}
.pick small{color:var(--mute);font-size:11px;text-align:center;line-height:1.35}

/* ---------------------------------------------------------------- settings */
.srow{display:flex;align-items:center;gap:14px;padding:14px 0;border-bottom:1px solid #151d29}
.srow:last-child{border-bottom:0}
.srow .lab{flex:1;min-width:0}
.srow .lab b{display:block;font-size:14px;margin-bottom:2px}
.srow .lab small{color:var(--mute);font-size:12px}
select,input[type=text],input[type=password],input[type=number]{
  background:var(--panel2);border:1px solid var(--line);border-radius:9px;padding:9px 12px;min-width:160px;
}
select:focus,input:focus{outline:2px solid rgba(255,90,31,.5);outline-offset:1px}
.sw{width:50px;height:28px;border-radius:999px;background:#212c3d;position:relative;transition:.2s;flex:none}
.sw::after{content:"";position:absolute;top:3px;left:3px;width:22px;height:22px;border-radius:50%;background:#64748b;transition:.2s}
.sw.on{background:rgba(255,90,31,.35)}
.sw.on::after{transform:translateX(22px);background:var(--hot)}
.locked{opacity:.5;pointer-events:none}

/* ------------------------------------------------------------------- brain */
.brainwrap{position:relative;background:radial-gradient(circle at 50% 45%,#111a29,#070a10);border:1px solid var(--line);border-radius:var(--r);overflow:hidden;height:560px}
.brainwrap canvas{display:block;width:100%;height:100%;cursor:grab}
.brainwrap canvas:active{cursor:grabbing}
.legend{position:absolute;left:14px;top:14px;display:flex;flex-direction:column;gap:7px;pointer-events:none}
.legend div{display:flex;align-items:center;gap:8px;font:600 11px/1 var(--mono);color:var(--mute)}
.legend i{width:10px;height:10px;border-radius:50%}
.nodecard{
  position:absolute;right:14px;top:14px;width:250px;background:rgba(10,14,21,.93);
  backdrop-filter:blur(10px);border:1px solid var(--line);border-radius:12px;padding:14px;display:none;
}
.nodecard.on{display:block}
.nodecard b{display:block;font:800 15px/1.2 var(--mono);margin-bottom:5px}
.nodecard small{color:var(--mute);font-size:12px;line-height:1.5;display:block}

/* ---------------------------------------------------------------- sessions */
.slist{display:flex;flex-direction:column;gap:10px}
.sitem{
  width:100%;text-align:left;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);padding:15px;display:grid;grid-template-columns:auto 1fr auto;
  gap:14px;align-items:center;transition:.14s;
}
.sitem:hover{border-color:var(--hot);transform:translateX(3px)}
.sitem .ball{width:44px;height:44px;flex:none}
.sitem b{display:block;font:700 15px/1.3 var(--mono)}
.sitem small{color:var(--mute);font-size:12px}
.sitem .score{font:800 21px/1 var(--mono);color:var(--hot)}

/* ------------------------------------------------------------------- modal */
.modal{position:fixed;inset:0;background:rgba(3,5,9,.88);backdrop-filter:blur(7px);display:none;place-content:center;padding:22px;z-index:300}
.modal.open{display:grid}
.sheet{background:var(--panel);border:1px solid var(--line);border-radius:17px;max-width:680px;width:100%;max-height:86vh;overflow:auto;padding:26px}
.sheet h2{font:800 22px/1.2 var(--mono);letter-spacing:-.7px;margin-bottom:4px}
.sheet .sub{color:var(--mute);font-size:13px;margin-bottom:19px}
.sheet section{margin-bottom:20px}
.sheet section h4{font:700 10px/1 var(--mono);letter-spacing:1.5px;text-transform:uppercase;color:var(--hot);margin-bottom:9px}
.sheet p{line-height:1.68;white-space:pre-wrap}
.qa{border-left:2px solid var(--line);padding-left:13px;margin-bottom:13px}
.qa b{display:block;font-size:13px;color:var(--cool);margin-bottom:4px}
.log{display:flex;flex-wrap:wrap;gap:5px}
.chip{font:700 11px/1 var(--mono);padding:6px 9px;border-radius:7px;background:var(--panel2);border:1px solid var(--line)}
.chip.made{border-color:#1d6b42;color:var(--good)}
.chip.missed{border-color:#7a2033;color:var(--bad)}

/* ------------------------------------------------------------- talk bubble */
.talkbar{
  position:fixed;left:50%;bottom:22px;transform:translateX(-50%);z-index:95;
  display:flex;align-items:center;gap:11px;background:rgba(14,19,27,.95);
  backdrop-filter:blur(14px);border:1px solid var(--line);border-radius:999px;
  padding:9px 9px 9px 18px;box-shadow:0 16px 50px rgba(0,0,0,.6);max-width:min(620px,92vw);
}
.talkbar input{background:none;border:0;min-width:0;flex:1;font-size:14.5px}
.talkbar input:focus{outline:none}
.talkbar .go{width:40px;height:40px;border-radius:50%;background:var(--hot);color:#0a0a0a;display:grid;place-content:center;font-size:17px;flex:none}
.talkbar .mic{width:40px;height:40px;border-radius:50%;background:var(--panel2);border:1px solid var(--line);display:grid;place-content:center;font-size:16px;flex:none}
.talkbar .mic.rec{background:var(--bad);border-color:var(--bad);animation:pulse 1.1s infinite}

/* ============================================================ rail: layering
   The rail is position:sticky, which makes it a stacking context. The dashboard
   cards are position:relative later in the DOM, so at z-index auto they painted
   OVER the rail and swallowed the hover labels. Lifting the whole rail above the
   content column fixes every label at once, and stays under the dock, the talk
   bar, the radio and the modal so none of those change behaviour. */
.rail{z-index:60}

/* The rail is now thirteen items tall, which overflows a laptop screen, so it
   has to scroll. A scroll container clips its children, which would eat the
   labels we just lifted, so in collapsed mode the label is position:fixed and
   app.js sets its top from the button it belongs to. Fixed escapes the scroll
   box entirely, and the rail's own z-index keeps it over the content. */
.rail{overflow-y:auto;overflow-x:hidden;scrollbar-width:none}
.rail::-webkit-scrollbar{width:0;height:0}
.rail button .tip{position:fixed;left:var(--rail-tip-x,84px);top:0;transform:translate(-6px,-50%)}
.rail button:hover .tip{transform:translate(0,-50%)}
@media(max-width:900px){.rail{--rail-tip-x:64px}}

/* ------------------------------------------------- rail: collapse and expand
   One markup, two presentations. Collapsed is the icon rail with a floating
   label on hover. Expanded turns that same .tip into an inline label, so the
   whole menu reads at a glance. The state is written to localStorage and
   applied by /js/theme.js before first paint, so it never flashes. */
.rail-toggle{color:var(--dim)}
.rail-toggle b{font:900 17px/1 var(--mono);display:block;transition:transform .22s cubic-bezier(.2,.9,.3,1.3)}
.rail-toggle:hover{color:var(--hot)}
:root[data-rail="open"] .rail-toggle b{transform:rotate(180deg)}

:root[data-rail="open"] .shell{grid-template-columns:214px 1fr}
:root[data-rail="open"] .rail{align-items:stretch;padding:16px 12px;gap:4px}
:root[data-rail="open"] .rail .logo{margin:0 auto 10px}
:root[data-rail="open"] .rail button{
  width:100%;height:46px;display:flex;align-items:center;justify-content:flex-start;
  gap:12px;padding:0 12px;font-size:19px;
}
/* the tooltip becomes the label */
:root[data-rail="open"] .rail button .tip{
  position:static!important;opacity:1!important;background:none!important;top:auto!important;left:auto!important;
  color:inherit!important;border:0!important;box-shadow:none!important;
  padding:0!important;border-radius:0!important;transform:none!important;
  font:800 13.5px/1 var(--mono)!important;letter-spacing:.1px;white-space:nowrap;
}
:root[data-rail="open"] .rail button.on::before{left:-12px;top:9px;bottom:9px}
:root[data-rail="open"] .rail button:hover{transform:translateX(2px) scale(1)}
:root[data-rail="open"] .rail button.on{transform:none}
:root[data-rail="open"] .rail .theme-sw{justify-content:flex-start;gap:12px;padding:0 12px;height:46px;border-radius:14px}
:root[data-rail="open"] .rail .theme-sw span:not(.tip){display:inline;font:800 13.5px/1 var(--mono);color:inherit}
:root[data-rail="open"] .rail .theme-sw .tip{display:none!important}
:root[data-rail="open"] .rail-toggle{justify-content:space-between}

/* On a phone the expanded rail floats over the content instead of squeezing it
   to nothing. The box-shadow is the scrim, so there is no extra element to
   manage, and tapping any tab closes it (see app.js). */
@media(max-width:900px){
  :root[data-rail="open"] .shell{grid-template-columns:56px 1fr}
  :root[data-rail="open"] .rail{
    position:fixed;left:0;top:0;bottom:0;width:216px;z-index:210;
    box-shadow:0 0 0 100vmax rgba(3,5,9,.6);
  }
}
@media(prefers-reduced-motion:reduce){.rail-toggle b{transition:none}}

/* ------------------------------------------------ rail: collapsible sections
   Each heading is a disclosure button that opens and closes its own group. The
   open and closed heights animate exactly, with the 1fr to 0fr grid technique,
   so nothing has to guess a pixel height. Collapsed to icons, sections are
   forced open and the heading becomes a hairline: an icon you cannot see is an
   icon you cannot find. */
.rail-sec{display:flex;flex-direction:column}
.rail-group{
  display:none;width:100%;align-items:center;gap:6px;
  font:800 9px/1 var(--mono);letter-spacing:1.4px;text-transform:uppercase;
  color:var(--dim);padding:14px 12px 7px;border-radius:10px;transition:color .16s,background .16s;
}
.rail-group span{flex:1;text-align:left}
.rail-group i{font-style:normal;font-size:13px;transition:transform .26s cubic-bezier(.2,.9,.3,1.3);transform:rotate(90deg)}
.rail-group:hover{color:var(--hot)}
.rail-group:focus-visible{outline:2px solid var(--hot);outline-offset:1px}
.rail-sec.closed .rail-group i{transform:rotate(0deg)}
.rail-sec.closed .rail-group{color:var(--mute)}

.rail-items{display:grid;grid-template-rows:1fr;transition:grid-template-rows .28s cubic-bezier(.2,.9,.3,1),opacity .22s}
.rail-items>div{overflow:hidden;display:flex;flex-direction:column;gap:4px;min-height:0}
.rail-sec.closed .rail-items{grid-template-rows:0fr;opacity:0}

/* a closed section still says how many things are inside it */
.rail-group b{font:800 9px/1 var(--mono);color:var(--hot);opacity:0;transition:opacity .2s}
.rail-sec.closed .rail-group b{opacity:1}

:root[data-rail="open"] .rail-group{display:flex}
/* icon rail: no headings, no collapsing, just a rule between the groups */
:root:not([data-rail="open"]) .rail-sec+.rail-sec{border-top:1px solid var(--line);margin-top:8px;padding-top:8px}
:root:not([data-rail="open"]) .rail-items{grid-template-rows:1fr!important;opacity:1!important}

/* ============================================== rail: a colour per section
   Five sections, five hues. One custom property on .rail-sec drives the
   heading, every tab label and every icon underneath it, so a section reads
   as one colour and the heading and its tabs are never a different shade of
   the same idea. The values and the reasoning behind the two steps live with
   the tokens at the end of base.css.

   The three states are deliberately different in kind, not only in strength:
     rest    the section colour, no background
     hover   the colour one step up, a light wash of it behind the row
     active  the same step up, a heavier wash, a ring around the row, the left
             bar and a heavier word
   so a hover can never be mistaken for the tab you are on. */
.rail-sec[data-sec="training"] {--sec:var(--rail-training);  --sec-up:var(--rail-training-up)}
.rail-sec[data-sec="body"]     {--sec:var(--rail-body);      --sec-up:var(--rail-body-up)}
.rail-sec[data-sec="companion"]{--sec:var(--rail-companion); --sec-up:var(--rail-companion-up)}
.rail-sec[data-sec="people"]   {--sec:var(--rail-people);    --sec-up:var(--rail-people-up)}
.rail-sec[data-sec="sound"]    {--sec:var(--rail-sound);     --sec-up:var(--rail-sound-up)}

/* the heading and the tabs under it, the same colour */
.rail .rail-sec .rail-group,
.rail .rail-sec.closed .rail-group,
.rail .rail-sec .rail-items button{color:var(--sec)}
.rail .rail-sec .rail-group b{color:var(--sec)}

/* hover: the colour arrives, the row picks up a wash of it. The day theme is
   named as well because base.css pins every rail hover to the ink colour. */
.rail .rail-sec .rail-items button:hover,
:root[data-theme="day"] .rail .rail-sec .rail-items button:hover{
  color:var(--sec-up);
  background:color-mix(in srgb, var(--sec) 13%, transparent);
}
/* The day theme is named here too. base.css pins every rail hover to the ink
   colour with `:root[data-theme="day"] .rail button:hover`, and a heading IS a
   button, so without the second selector a green section's heading turned near
   black with an orange wash the moment the pointer touched it. The tab rule
   above already carried its day twin; this one did not. */
.rail .rail-sec .rail-group:hover,
:root[data-theme="day"] .rail .rail-sec .rail-group:hover{
  color:var(--sec-up);
  background:color-mix(in srgb, var(--sec) 11%, transparent);
}

/* active: heavier wash, a ring, the bar and a heavier word. Declared after
   hover so the tab you are on keeps its own look while the pointer is on it. */
.rail .rail-sec .rail-items button.on,
:root[data-theme="day"] .rail .rail-sec .rail-items button.on{
  color:var(--sec-up);
  background:color-mix(in srgb, var(--sec) 28%, transparent);
  box-shadow:inset 0 0 0 1.5px color-mix(in srgb, var(--sec) 70%, transparent);
}
/* expanded, the active word is heavier too. !important because the label
   rule that turns a tooltip into a label pins the whole font shorthand. */
:root[data-rail="open"] .rail .rail-sec .rail-items button.on .tip{font-weight:900!important}
.rail .rail-sec .rail-items button.on::before{background:var(--sec-up)}
/* Same reason, one level deeper: the day hover twin above outranks this rule
   unless it carries the theme too, and without it hovering the tab you are on
   made its wash lighter instead of heavier. */
.rail .rail-sec .rail-items button.on:hover,
:root[data-theme="day"] .rail .rail-sec .rail-items button.on:hover{
  background:color-mix(in srgb, var(--sec) 32%, transparent);
}

/* keyboard: the same hue as the section, so the ring says where you are */
.rail .rail-sec .rail-items button:focus-visible,
.rail .rail-sec .rail-group:focus-visible{
  outline:2px solid var(--sec-up);outline-offset:2px;
}

/* Home, Settings and Sign out sit outside the sections and stay on the brand
   orange. The token exists because the raw brand orange is only 3:1 on the
   white day rail, which is not enough for a word. Their resting grey moves off
   --dim for the same reason: --dim is 3.3:1 on the night rail. */
.rail>button{color:var(--mute)}
.rail>button.on{color:var(--rail-anchor)}
.rail>button.on::before{background:var(--rail-anchor)}

/* Collapsed, the headings are gone, so the hairline between two groups and the
   floating label carry the colour instead. Both are decorative: if color-mix
   is missing the rule drops and the plain rule underneath still applies. */
:root:not([data-rail="open"]) .rail .rail-sec+.rail-sec{
  border-top-color:color-mix(in srgb, var(--sec) 34%, transparent);
}
.rail .rail-sec .tip{box-shadow:0 8px 24px rgba(0,0,0,.25),inset 3px 0 0 var(--sec)}

/* Collapsed, the lift moves off the button and onto the glyph. A transformed
   element becomes the containing block for anything position:fixed inside it,
   and the floating label is fixed, so lifting the button itself took the label
   with it and dropped it hundreds of pixels down the page. The rail feels the
   same, the label lands where app.js put it. */
:root:not([data-rail="open"]) .rail button:hover,
:root:not([data-rail="open"]) .rail button.on,
:root:not([data-rail="open"]) .rail button:active{transform:none}
:root:not([data-rail="open"]) .rail button .hb-i,
:root:not([data-rail="open"]) .rail .theme-sw i{transition:transform .16s cubic-bezier(.2,.9,.3,1.3)}
:root:not([data-rail="open"]) .rail button:hover .hb-i,
:root:not([data-rail="open"]) .rail .theme-sw:hover i{transform:translateY(-2px) scale(1.12)}
:root:not([data-rail="open"]) .rail button.on .hb-i{transform:scale(1.1)}
:root:not([data-rail="open"]) .rail button:active .hb-i{transform:scale(.92)}

@media(prefers-reduced-motion:reduce){
  .rail button,.rail-group,.rail-items,.rail button .hb-i{transition:none}
  .rail button:hover,:root[data-rail="open"] .rail button:hover,
  .rail button.on,.rail button:active{transform:none}
  :root:not([data-rail="open"]) .rail button:hover .hb-i,
  :root:not([data-rail="open"]) .rail button.on .hb-i,
  :root:not([data-rail="open"]) .rail button:active .hb-i{transform:none}
}

/* The heading is a disclosure button, so `.rail button` matches it and outranks
   `.rail-group` on specificity. That handed the headings a display, a 19px font
   and a 48px box: expanded, "Your companion" wrapped onto two lines, and
   collapsed they were drawn over the icon rail at 19px instead of hiding.
   These two rules take the heading back off `.rail button` and put it back to
   the micro label it was drawn as, at the 10px the cards already use. */
.rail .rail-sec .rail-group{display:none}
:root[data-rail="open"] .rail .rail-sec .rail-group{
  display:flex;height:auto;padding:15px 12px 6px;gap:6px;
  font:800 10px/1.2 var(--mono);letter-spacing:1.5px;white-space:nowrap;
}

/* ================================= rail: the rows outside the five sections
   Home, Your record, the day and night switch, Settings and Sign out sit
   outside the five coloured groups, so on a menu built around colour they were
   the only grey rows left. Each one now carries a hue of its own, picked to
   land in the gaps between the five section hues so no row is mistaken for a
   group: gold for Home, lime for Your record, indigo for the switch, teal for
   Settings, rose for Sign out. The three states are the ones the sections
   already use, so a row outside a group behaves exactly like a row inside one.

   Every value was measured on the rail it sits on, in all four states, against
   the row background composited over the rail. The worst reading of the lot is
   5.1:1 on the white day rail and 5.7:1 on the night one, so none of these rows
   is the floor: the lowest in the whole rail is still a section tab at its
   heaviest wash, 4.9:1 by day and 5.4:1 by night.

   A row added here later gets no hue and falls back to the resting grey, which
   is the thing this block exists to remove. Give it a token and add it to the
   lists below.

   The tokens are declared on .rail rather than :root because base.css, where
   the section hues live, is not this file's to edit.

   On the selector: the rows share one :is() list. Its specificity is the
   heaviest argument, and [id="btnOut"] is written as an attribute rather than
   an id so the whole list stays at one class. That leaves the states tunable
   later and still clears `.rail button[data-view="dashboard"].on` in base.css.
   The day theme is named on hover and on active for the same reason the
   section rules name it: base.css pins every rail hover to the ink colour. */
.rail{
  --rail-home:#ffc862;     --rail-home-up:#ffdb96;
  --rail-record:#b6e06a;   --rail-record-up:#d2ec9e;
  --rail-theme:#a3b0ff;    --rail-theme-up:#c4ccff;
  --rail-settings:#4fd9cf; --rail-settings-up:#8ceee7;
  --rail-exit:#ff9090;     --rail-exit-up:#ffb9b9;
}
:root[data-theme="day"] .rail{
  --rail-home:#8a5a06;     --rail-home-up:#6b4504;
  --rail-record:#4d6b09;   --rail-record-up:#3a5107;
  --rail-theme:#3d35a8;    --rail-theme-up:#2e2887;
  --rail-settings:#0a6b68; --rail-settings-up:#075250;
  --rail-exit:#b32036;     --rail-exit-up:#8f1728;
}
.rail>button[data-view="dashboard"]{--row:var(--rail-home);    --row-up:var(--rail-home-up)}
.rail>button[data-view="career"]   {--row:var(--rail-record);  --row-up:var(--rail-record-up)}
.rail>.theme-sw                    {--row:var(--rail-theme);   --row-up:var(--rail-theme-up)}
.rail>button[data-view="settings"] {--row:var(--rail-settings);--row-up:var(--rail-settings-up)}
.rail>[id="btnOut"]                {--row:var(--rail-exit);    --row-up:var(--rail-exit-up)}

/* rest */
.rail>:is(button[data-view="dashboard"],button[data-view="career"],button[data-view="settings"],[id="btnOut"],.theme-sw){
  color:var(--row);
}
/* hover: the colour one step up, a light wash of it behind the row */
.rail>:is(button[data-view="dashboard"],button[data-view="career"],button[data-view="settings"],[id="btnOut"],.theme-sw):hover,
:root[data-theme="day"] .rail>:is(button[data-view="dashboard"],button[data-view="career"],button[data-view="settings"],[id="btnOut"],.theme-sw):hover{
  color:var(--row-up);
  background:color-mix(in srgb, var(--row) 13%, transparent);
}
/* the switch is the one row with a border of its own, so it warms up too */
.rail>.theme-sw:hover,:root[data-theme="day"] .rail>.theme-sw:hover{
  border-color:color-mix(in srgb, var(--row) 55%, transparent);
}
/* active: heavier wash, a ring, the bar and a heavier word. Declared after
   hover so the row you are on keeps its own look while the pointer is on it. */
.rail>:is(button[data-view="dashboard"],button[data-view="career"],button[data-view="settings"],[id="btnOut"],.theme-sw).on,
:root[data-theme="day"] .rail>:is(button[data-view="dashboard"],button[data-view="career"],button[data-view="settings"],[id="btnOut"],.theme-sw).on{
  color:var(--row-up);
  background:color-mix(in srgb, var(--row) 28%, transparent);
  box-shadow:inset 0 0 0 1.5px color-mix(in srgb, var(--row) 70%, transparent);
}
.rail>:is(button[data-view="dashboard"],button[data-view="career"],button[data-view="settings"],[id="btnOut"],.theme-sw).on:hover,
:root[data-theme="day"] .rail>:is(button[data-view="dashboard"],button[data-view="career"],button[data-view="settings"],[id="btnOut"],.theme-sw).on:hover{
  background:color-mix(in srgb, var(--row) 32%, transparent);
}
.rail>:is(button[data-view="dashboard"],button[data-view="career"],button[data-view="settings"],[id="btnOut"],.theme-sw).on::before{
  background:var(--row-up);
}
.rail>:is(button[data-view="dashboard"],button[data-view="career"],button[data-view="settings"],[id="btnOut"],.theme-sw):focus-visible{
  outline:2px solid var(--row-up);outline-offset:2px;
}
/* collapsed, the floating label carries the row colour the way a section's
   label carries the section colour */
.rail>:is(button[data-view="dashboard"],button[data-view="career"],button[data-view="settings"],[id="btnOut"],.theme-sw) .tip{
  box-shadow:0 8px 24px rgba(0,0,0,.25),inset 3px 0 0 var(--row);
}
