/* Infinite Solutions — PTO dashboard design system.
   Shared by every page. Token names are production's (--paper, --canvas, --muted,
   --rule, --accent, --moss ...) because pto-calc.js injects markup that references
   them; the values are the Executive palette.

   Sizing: the page is driven by viewport HEIGHT. Every clamp is (floor, vh term,
   ceiling) — a shallow laptop screen closes the whitespace up and eases the display
   numerals down, a tall screen spends the room on larger type. Reading text floors
   at ~12.5px and only starts growing past ~800px tall, so it is legible at every
   size. The arrangement never changes: no card moves or reflows with height. */

:root{
  --canvas:#F2EEE5; --paper:#FFFFFF; --ink:#1E1A15; --muted:#6F6757; --rule:#E7E1D6;
  --blue:#014A73; --on-blue:#F4EFE6; --blueline:rgba(255,255,255,.15); --bluesub:#AFCADB;
  --accent:#C33E1D; --moss:#1D7A44; --amber:#A9701A;
  --amber-bg:#FBF0DA; --amber-line:#E9D3A6; --amber-ink:#7A5214;
  --green-bg:#E6F1EA; --green-ink:#1B6E43;
  --red-bg:#F8E7E2; --red-ink:#8F2A13;
  --track:#ECE6DA; --hover:#EAF1F5;
  /* carried from the previous production sheet so existing markup keeps resolving */
  --cream:#FEF4E8; --paper-dark:#F6E7D5; --accent-deep:#9E2F15; --accent-bright:#EE7522;
  --moss-light:#2C9456; --danger:#B3261E; --warning:#EE7522;
  --radius:12px; --shadow:0 3px 12px rgba(26,26,26,.06);
  /* Browser-painted UI — <select> popups, the date and time pickers, scrollbars,
     checkboxes — follows color-scheme, not our tokens. Without it the whole app
     kept the light widgets in dark mode: the "View as" list came out as pale grey
     text on a white popup, and every date picker opened white. */
  color-scheme:light;
  /* vertical rhythm */
  --vgap:clamp(.42rem,1.28vh,1.15rem);
  --cardpad:clamp(.42rem,1.18vh,1.05rem);
}
@media (prefers-color-scheme: dark){
  :root{ --canvas:#14120F; --paper:#211E19; --ink:#ECE6DB; --muted:#A79E90; --rule:#332E27;
    --blue:#0F3B58; --on-blue:#EAF2F8; --bluesub:#8FB6CE; --blueline:rgba(255,255,255,.12);
    --accent:#E0682F; --moss:#4CAE6E; --amber:#E0A24A;
    --amber-bg:#3A2A16; --amber-line:#5A4327; --amber-ink:#F2C79E;
    --green-bg:#1C2A22; --green-ink:#8FD3A6;
    --red-bg:#3A211B; --red-ink:#F0A88F;
    --track:#3A342B; --hover:#26221C;
    --cream:#2A241C; --paper-dark:#2A241C; --accent-deep:#E0682F; --accent-bright:#F08A46;
    --moss-light:#6BC489; --danger:#F0A88F; --warning:#E0A24A;
    --shadow:0 6px 20px rgba(0,0,0,.35);
    color-scheme:dark; }
}
:root[data-theme="dark"]{ --canvas:#14120F; --paper:#211E19; --ink:#ECE6DB; --muted:#A79E90; --rule:#332E27;
  --blue:#0F3B58; --on-blue:#EAF2F8; --bluesub:#8FB6CE; --blueline:rgba(255,255,255,.12);
  --accent:#E0682F; --moss:#4CAE6E; --amber:#E0A24A; --amber-bg:#3A2A16; --amber-line:#5A4327;
  --amber-ink:#F2C79E; --green-bg:#1C2A22; --green-ink:#8FD3A6; --red-bg:#3A211B; --red-ink:#F0A88F;
  --track:#3A342B; --hover:#26221C; --cream:#2A241C; --paper-dark:#2A241C; --accent-deep:#E0682F;
  --accent-bright:#F08A46; --moss-light:#6BC489; --danger:#F0A88F; --warning:#E0A24A;
  --shadow:0 6px 20px rgba(0,0,0,.35);
  color-scheme:dark; }
:root[data-theme="light"]{ --canvas:#F2EEE5; --paper:#FFFFFF; --ink:#1E1A15; --muted:#6F6757; --rule:#E7E1D6;
  --blue:#014A73; --on-blue:#F4EFE6; --bluesub:#AFCADB; --blueline:rgba(255,255,255,.15);
  --accent:#C33E1D; --moss:#1D7A44; --amber:#A9701A; --amber-bg:#FBF0DA; --amber-line:#E9D3A6;
  --amber-ink:#7A5214; --green-bg:#E6F1EA; --green-ink:#1B6E43; --red-bg:#F8E7E2; --red-ink:#8F2A13;
  --track:#ECE6DA; --hover:#EAF1F5; --cream:#FEF4E8; --paper-dark:#F6E7D5; --accent-deep:#9E2F15;
  --accent-bright:#EE7522; --moss-light:#2C9456; --danger:#B3261E; --warning:#EE7522;
  --shadow:0 3px 12px rgba(26,26,26,.06);
  color-scheme:light; }

*{ box-sizing:border-box; }
/* Always reserve the scrollbar gutter. My Team's table is long enough to scroll
   while the other pages fit, and a scrollbar narrows the viewport — which slid the
   centred container 7px left on that page only, so the content visibly jumped as
   you moved between pages. */
html{ scrollbar-gutter:stable; }
body{ margin:0; font-family:'Hanken Grotesk',system-ui,sans-serif; background:var(--canvas); color:var(--ink); }
.num{ font-variant-numeric:tabular-nums; }
.disp{ font-family:'Bricolage Grotesque',serif; letter-spacing:-.02em; }

/* ---- Masthead ---- */
.mh{ background:var(--paper); border-bottom:1px solid var(--rule); }
/* min-height keeps the bar the same depth whether or not the page carries the
   Request button, so the nav sits on the same line everywhere too.

   THIS BAR IS SHARED WITH inf-learning-repo, which serves the certification tracker, the org
   chart, the DISC board, Leading Your Team and The Infinite WAY. Staff move between the two
   apps as if they were one, and until 2026-09-15 they did not match: this sheet's logo and
   title were the largest of the three copies, org-chart.html's the smallest. The width, the
   bar depth, the logo height and the title size below are now identical in all three places
   (here, inf-learning-repo/web/app.css, and the inline copy in org-chart.html). Change one,
   change all three, then measure. */
.mh-in{ max-width:1500px; margin:0 auto; display:flex; align-items:center;
  justify-content:space-between; gap:1.5rem; flex-wrap:wrap;
  min-height:clamp(52px,7vh,76px);
  padding:clamp(.42rem,1vh,.8rem) clamp(1rem,3vw,2rem); }
/* Three zones: brand, nav, actions. The brand zone holds a fixed width so the nav
   starts at the same x on every page — page titles differ in length, and letting the
   nav follow them made the links jump as you moved between pages. */
.mh-l{ display:flex; align-items:center; gap:.9rem; flex:0 0 clamp(230px,26vw,360px); min-width:0; }
.mh-nav{ display:flex; gap:.2rem; flex-wrap:wrap; flex:1 1 auto; }
.mh-r{ margin-left:auto; }
.mh-logo{ height:clamp(22px,3vh,32px); width:auto; display:block; }
:root[data-theme="dark"] .mh-logo{ filter:brightness(1.55); }
@media (prefers-color-scheme: dark){ .mh-logo{ filter:brightness(1.55); } }
:root[data-theme="light"] .mh-logo{ filter:none; }
.mh-div{ width:1px; height:26px; background:var(--rule); }
.mh-title{ font-size:clamp(.95rem,1.9vh,1.2rem); font-weight:700; }
.mh-title span{ font-weight:400; color:var(--muted); font-style:italic; }
.mh-r{ display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; }
.nav{ color:var(--blue); text-decoration:none; font-size:clamp(.82rem,1.64vh,.96rem); font-weight:600;
  padding:.45rem .7rem; border-radius:8px; }
:root[data-theme="dark"] .nav{ color:var(--bluesub); }
.nav:hover{ background:var(--hover); }
/* the page you are on keeps its slot so the row never reflows between pages */
.nav.current{ color:var(--ink); background:var(--track); cursor:default; }
.picker{ display:flex; align-items:center; gap:.45rem; border:1px solid var(--rule); border-radius:8px;
  padding:clamp(.3rem,.6vh,.45rem) .55rem; font-size:clamp(.82rem,1.64vh,.96rem); background:var(--paper); }
.picker .lbl{ color:var(--muted); font-size:clamp(.78rem,1.56vh,.92rem); }
.picker select{ border:none; background-color:var(--paper); color:var(--ink); font:inherit;
  font-size:clamp(.82rem,1.64vh,.96rem); }
/* Matches .picker's own fill, so the closed control looks unchanged while the open
   list has a surface to sit on. Firefox/Windows reads these for the popup. */
.picker select option{ background-color:var(--paper); color:var(--ink); }
.req-field select option{ background-color:var(--canvas); color:var(--ink); }
.req{ background:var(--accent); color:#fff; border:none; border-radius:8px;
  padding:clamp(.55rem,1.1vh,.7rem) clamp(1.1rem,2.2vh,1.4rem); font-size:clamp(.86rem,1.72vh,1rem);
  font-weight:600; cursor:pointer; text-decoration:none; }
:root[data-theme="dark"] .req{ color:#160c06; }
.req:hover{ filter:brightness(1.06); }
.theme-btn{ background:var(--paper); border:1px solid var(--rule); color:var(--muted); border-radius:8px;
  padding:.4rem .55rem; cursor:pointer; font-size:.85rem; }

/* Negative-balance strip — full bleed directly under the masthead, as it was before
   the redesign. It sits outside .container on purpose: edge to edge is what makes it
   read as an alert rather than another card. Its own colours rather than --danger,
   which in dark mode is a light salmon meant for text, not a background. */
.negative-banner{ background:#B3261E; color:#fff; }
/* Background runs edge to edge; the text lines up with the masthead and the cards,
   same max-width and padding as .mh-in / .container. */
.nb-in{ max-width:1500px; margin:0 auto; padding:.45rem clamp(1rem,3vw,2rem);
  font-size:clamp(.8rem,1.6vh,.94rem); letter-spacing:.01em; }
.negative-banner strong{ text-transform:uppercase; letter-spacing:.14em;
  font-weight:700; margin-right:.5rem; }
:root[data-theme="dark"] .negative-banner{ background:#7A1E17; color:#FFE8E3; }
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .negative-banner{ background:#7A1E17; color:#FFE8E3; }
}

/* ---- Page shell ---- */
.container{ max-width:1500px; margin:0 auto; display:flex; flex-direction:column;
  padding:clamp(.35rem,.95vh,.8rem) clamp(1rem,3vw,2rem) clamp(.2rem,.4vh,.4rem); gap:var(--vgap); }
/* Pages render into #dash / #main, so the row gap has to be set there too — on
   .container it only ever spaces the rendered block from the footer. */
#dash,#main{ display:flex; flex-direction:column; gap:var(--vgap); }
/* no horizontal inset — the heading shares its left edge with the cards, the
   masthead and the over-balance banner */
.greet{ display:flex; align-items:baseline; justify-content:space-between; gap:1.5rem; flex-wrap:wrap;
  border-bottom:1px solid var(--rule); padding:0 0 clamp(.2rem,.6vh,.35rem); }
.greet h1{ font-size:clamp(1.15rem,2.65vh,1.85rem); margin:0; }
.greet h1 em{ font-style:normal; color:var(--accent); }
.greet .meta{ font-size:clamp(.82rem,1.64vh,.96rem); color:var(--muted); display:flex; gap:1.1rem; flex-wrap:wrap; }
.greet .meta b{ color:var(--ink); font-weight:600; }
/* View as, moved here from the masthead on 2026-10-22 so the admin masthead stays on one line. It sits on
   the right beside the tenure line, and above the dashboard until the first render moves it in. */
.greet .picker{ margin-left:auto; align-self:center; }
.container > .picker{ width:max-content; margin:0 0 .5rem auto; }
.pagehead{ display:flex; align-items:baseline; justify-content:space-between; gap:1rem; flex-wrap:wrap;
  border-bottom:1px solid var(--rule); padding:0 0 clamp(.2rem,.6vh,.35rem); }
.pagehead h1{ font-size:clamp(1.15rem,2.65vh,1.85rem); margin:0; }
.foot{ color:var(--muted); font-size:clamp(.78rem,1.56vh,.92rem); font-style:italic; padding:0 .2rem; }
/* Sits under the provenance line. Upright rather than italic: it is an instruction
   to act on, not a caption about the data. Three destinations is more than a
   sentence carries well, so each is its own line and the destination is the part
   set in ink — people scan for their situation, then need the answer to stand out. */
.foot.help-note{ font-style:normal; margin-top:.45rem; }
/* Contacts on the left and the provenance line on the right, so the contacts sit
   directly under the cards instead of below a full-width caption. They stack on a
   narrow screen, contacts first, because that is the part someone acts on. */
.foot-row{ display:flex; align-items:flex-start; justify-content:space-between; gap:1.5rem; }
.foot-row .foot.help-note{ margin-top:0; flex:1 1 auto; min-width:0; }
.foot-row .foot-prov{ flex:0 1 26rem; text-align:right; text-wrap:balance; }
@media (max-width:900px){
  .foot-row{ flex-direction:column; gap:.6rem; }
  .foot-row .foot-prov{ flex:none; text-align:left; }
}
.foot.help-note .help-title{ font-weight:600; color:var(--ink); }
.foot.help-note ul{ margin:.1rem 0 0; padding-left:1.15rem;
  display:flex; flex-direction:column; gap:0; }
/* Tight line height so the contacts add as little as possible below the cards; the
   page is meant to fit one screen without scrolling. */
.foot-row .foot{ line-height:1.32; }
.foot.help-note b{ color:var(--ink); font-weight:600; }
/* nowrap so a name never breaks across two lines, which also keeps the tap
   target in one piece on a phone. Both names are well under the column. */
.foot.help-note a{ color:var(--blue); font-weight:600; text-decoration:none; white-space:nowrap; }
:root[data-theme="dark"] .foot.help-note a{ color:var(--bluesub); }
.foot.help-note a:hover{ text-decoration:underline; }
.loading{ padding:3rem; text-align:center; color:var(--muted); font-style:italic; }

/* One 12-column grid for every row, so card edges line up down the page. */
.g12{ display:grid; grid-template-columns:repeat(12,1fr); gap:var(--vgap); align-items:stretch; }
.s3{ grid-column:span 3; } .s4{ grid-column:span 4; } .s6{ grid-column:span 6; }
.s8{ grid-column:span 8; } .s12{ grid-column:span 12; }
/* Half-width cards two-up. The hero goes full width so the rows pair off cleanly —
   left at span 6 it shares a row with one stat, which pushes a tile up next to the
   other stat and strands the fourth tile on its own row. */
@media(max-width:1100px){ .s3,.s4{ grid-column:span 6; } .hero{ grid-column:span 12; } }
@media(max-width:700px){ .s3,.s4,.s6,.s8{ grid-column:span 12; } }

/* ---- Cards ---- */
.card{ background:var(--paper); border:1px solid var(--rule); border-radius:var(--radius);
  padding:var(--cardpad) 1rem; box-shadow:var(--shadow); display:flex; flex-direction:column; }
/* Reading text — labels, captions, list detail — never drops below ~12.5px. */
.lab{ font-size:clamp(.78rem,1.56vh,.92rem); font-weight:600; color:var(--muted); margin-bottom:.24rem; }
.sect-title{ font-size:clamp(1rem,2vh,1.2rem); font-weight:700; margin:0; }
/* pins a card's trailing block (bar, footer) to the bottom so they align card-to-card */
.pin{ margin-top:auto; padding-top:clamp(.32rem,.9vh,.55rem); }

.hero{ background:var(--blue); color:var(--on-blue); border-color:transparent; }
.hero .lab{ color:var(--bluesub); }
.hero-row{ display:flex; align-items:stretch; justify-content:space-between; gap:1.8rem; flex-wrap:wrap; }
.hero-l{ display:flex; flex-direction:column; justify-content:center; }
.hero-big{ font-size:clamp(1.8rem,4.6vh,3.3rem); font-weight:300; line-height:.9; letter-spacing:-.04em; }
.hero-big small{ font-size:clamp(.9rem,1.8vh,1.05rem); font-weight:400; color:var(--bluesub);
  margin-left:.35rem; letter-spacing:.03em; }
.hero-days{ color:rgba(255,255,255,.9); font-size:clamp(.86rem,1.72vh,1rem); font-style:italic; margin-top:.2rem; }
.hero-tab{ min-width:230px; font-size:clamp(.81rem,1.62vh,.96rem); border-left:1px solid var(--blueline);
  padding-left:1.2rem; display:flex; flex-direction:column; justify-content:center; }
.hero-tab .r{ display:flex; justify-content:space-between; gap:1rem; padding:clamp(.06rem,.26vh,.14rem) 0; }
.hero-tab .r span:first-child{ color:var(--bluesub); }
.hero-tab .r:last-child{ font-weight:700; margin-top:.2rem; padding-top:.32rem; border-top:1px dashed var(--blueline); }

.stat .v{ font-size:clamp(1.3rem,3.1vh,2.05rem); font-weight:400; line-height:1; letter-spacing:-.03em; }
.stat .v small{ font-size:clamp(.8rem,1.6vh,.94rem); color:var(--muted); font-weight:500; margin-left:.25rem; }
.cap{ font-size:clamp(.83rem,1.66vh,.97rem); color:var(--muted); margin-top:.2rem; }
.bar{ height:clamp(6px,.85vh,9px); border-radius:99px; background:var(--track); overflow:hidden;
  margin-top:clamp(.28rem,.8vh,.65rem); }
.bar i{ display:block; height:100%; border-radius:99px; }
.bar i.blue{ background:var(--blue); } .bar i.orange{ background:var(--accent); }
:root[data-theme="dark"] .bar i.blue{ background:var(--bluesub); }

.tile .v{ font-size:clamp(1.1rem,2.55vh,1.7rem); font-weight:400; line-height:1; letter-spacing:-.03em; }
.tile .v small{ font-size:clamp(.76rem,1.52vh,.9rem); color:var(--muted); font-weight:500;
  margin-left:.2rem; letter-spacing:.02em; }
.tile-status .v{ font-size:clamp(1.05rem,2.35vh,1.55rem); }
.status-chip{ margin-top:clamp(.2rem,.6vh,.45rem); }
/* Transparent wrapper: the four tiles are ordinary grid items of .g12. */
.facts{ display:contents; }

.chip{ display:inline-flex; align-items:center; gap:.4rem; font-size:clamp(.75rem,1.5vh,.88rem);
  font-weight:700; border-radius:999px; padding:.22rem .6rem; margin-top:.45rem; }
.chip.ok{ background:var(--green-bg); color:var(--green-ink); }
.chip.warn{ background:var(--amber-bg); color:var(--amber-ink); }
.chip.bad{ background:var(--red-bg); color:var(--red-ink); }
.chip.info{ background:var(--hover); color:var(--blue); }
:root[data-theme="dark"] .chip.info{ color:var(--bluesub); }
.dot{ width:7px; height:7px; border-radius:99px; background:currentColor; }

/* ---- Time off taken ---- */
.toff-head{ display:flex; align-items:center; gap:.6rem; margin-bottom:.3rem; }
.toff-badge{ font-size:clamp(.78rem,1.56vh,.92rem); font-weight:600; color:var(--blue);
  background:var(--hover); border-radius:99px; padding:.2rem .6rem; }
:root[data-theme="dark"] .toff-badge{ color:var(--bluesub); }
/* Grows on a roomy screen so more of the year shows unscrolled. */
.toff-list{ max-height:clamp(115px,27vh,430px); overflow-y:auto; scrollbar-width:thin; }
/* Wherever the Time off card shares a row with Accrual year, it takes that card's
   height and never sets the row's. The list sits absolutely inside .toff-box, so it
   adds nothing to the row however many instances there are, and scrolls inside it.
   Before 2026-10-12 the card grew with the list up to a 27vh cap, and a year with a
   dozen instances pushed the page 120px past a 1,040px laptop screen. */
@media (min-width:701px){
  .toff-card{ display:flex; flex-direction:column; }
  .toff-card .toff-box{ position:relative; flex:1 1 auto; min-height:7.5rem; }
  .toff-card .toff-box > .toff-list{ position:absolute; inset:0; max-height:none; }
}
/* A busy year: tighter rows, and each day breakdown kept to one line, with the full
   list in its tooltip. */
.toff-list.dense .toff-item{ padding:0; }
.toff-list.dense .toff-detail{ flex-wrap:nowrap; overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,#000 88%,transparent);
          mask-image:linear-gradient(90deg,#000 88%,transparent); }
.toff-list.dense .toff-detail > span{ flex:none; }
.nowrap{ white-space:nowrap; }
.toff-list::-webkit-scrollbar{ width:6px; }
.toff-list::-webkit-scrollbar-thumb{ background:var(--rule); border-radius:99px; }
/* Tighter rows come from the line-height, not smaller type — the text stays the same
   size so the list reads compact rather than cramped. */
.toff-item{ display:flex; align-items:baseline; gap:1rem; padding:clamp(.09rem,.3vh,.2rem) 0;
  line-height:1.28; border-top:1px solid var(--rule); }
.toff-when{ display:flex; align-items:baseline; gap:.45rem; white-space:nowrap; }
.toff-when .d{ font-weight:600; font-size:clamp(.93rem,1.86vh,1.08rem); }
.toff-when .s{ font-size:clamp(.79rem,1.58vh,.93rem); color:var(--muted); font-style:italic; }
.toff-detail{ flex:1; min-width:0; display:flex; flex-wrap:wrap; gap:.15rem .4rem;
  font-size:clamp(.79rem,1.58vh,.93rem); color:var(--muted); }
.toff-detail b{ color:var(--ink); font-weight:600; font-style:normal; }
.toff-detail .sep{ color:var(--rule); }
.toff-tot{ font-size:clamp(.93rem,1.86vh,1.08rem); font-weight:600; color:var(--accent);
  white-space:nowrap; margin-left:auto; }
.toff-more{ font-size:clamp(.8rem,1.6vh,.94rem); color:var(--muted); font-style:italic;
  padding-top:.6rem; border-top:1px solid var(--rule); }

/* ---- Accrual year ---- */
.meter{ display:grid; grid-template-columns:repeat(13,1fr); gap:5px; margin:clamp(.3rem,.85vh,.5rem) 0; }
.meter i{ height:clamp(14px,2.55vh,32px); border-radius:5px; background:var(--track); }
.meter i.done{ background:var(--blue); } .meter i.now{ background:var(--accent); }
:root[data-theme="dark"] .meter i.done{ background:var(--bluesub); }
.legend{ display:flex; gap:1.1rem; font-size:clamp(.79rem,1.58vh,.93rem); color:var(--muted); flex-wrap:wrap; }
.legend span{ display:flex; align-items:center; gap:.35rem; }
.legend .k{ width:10px; height:10px; border-radius:3px; }
.accr-foot{ display:grid; grid-template-columns:1fr 1fr; gap:1rem; border-top:1px solid var(--rule); }
.accr-foot .k{ display:block; color:var(--muted); font-size:clamp(.78rem,1.56vh,.92rem); font-weight:600; }
.accr-foot b{ display:block; color:var(--ink); font-size:clamp(1.1rem,2.2vh,1.35rem); font-weight:400;
  letter-spacing:-.02em; margin-top:.1rem; }

/* ---- Plan ahead ---- */
.plan-title{ margin-bottom:clamp(.4rem,1.28vh,1rem); }
/* The two halves sit on the page's own 12-column tracks, so the split between them
   falls exactly on the gap between the two cards above — and "What if I take time
   off?" starts on the same line as "Accrual year". The negative margin cancels the
   card's padding so the tracks match the grid outside it; each half puts that inset
   back so the text still lines up with the card's own edge. */
.plan{ display:grid; grid-template-columns:repeat(12,1fr); gap:var(--vgap);
  /* cancel the card's padding AND its 1px border, so these tracks are the page's
     tracks exactly — without the border the right-hand column lands 1px adrift */
  margin-left:calc(-1rem - 1px); margin-right:calc(-1rem - 1px); }
.plan > .plan-l{ grid-column:1 / span 6; padding:0 calc(1rem + 1px); }
.plan > .whatif{ grid-column:7 / span 6; padding:0 calc(1rem + 1px); }
/* Below ~1260px each half is too narrow to hold the forfeit notice on one line
   (and the three what-if inputs get cramped), so the two halves stack and take the
   full card width instead. Measured, not guessed: at 1210px the worst-case notice
   misses by a pixel, so the split needs to stop above that. */
@media(max-width:1260px){
  .plan{ grid-template-columns:1fr; margin-left:0; margin-right:0; }
  .plan > .plan-l, .plan > .whatif{ grid-column:1 / -1; padding:0; }
}
.plan-big{ font-size:clamp(1.45rem,3.55vh,2.35rem); font-weight:300; line-height:.95; letter-spacing:-.04em; }
.plan-big small{ font-size:clamp(.9rem,1.8vh,1.05rem); color:var(--muted); font-weight:500; margin-left:.3rem; }
.plan-note{ color:var(--muted); font-size:clamp(.88rem,1.76vh,1.02rem); margin-top:.15rem; line-height:1.4; }
.sched{ margin-top:clamp(.3rem,.85vh,.6rem); background:var(--canvas); border:1px solid var(--rule);
  border-radius:10px; padding:clamp(.35rem,.95vh,.5rem) .8rem; }
.sched .h{ font-size:clamp(.78rem,1.56vh,.92rem); font-weight:600; color:var(--muted); margin-bottom:.3rem; }
.sched .r{ display:flex; align-items:center; gap:.55rem; font-size:clamp(.88rem,1.76vh,1.02rem); padding:.08rem 0; }
.sched .r .d{ width:8px; height:8px; border-radius:99px; }
.sched .r .d.g{ background:var(--moss); } .sched .r .d.a{ background:var(--accent); }
.sched .r em{ font-style:normal; color:var(--muted); }
/* The rows are <button> now. Strip the UA button chrome so they still read as the
   plain lines they were, and put the affordance on a trailing "Review" rather
   than on a border, which would box in every line of a quiet summary block. */
.sched .r.sched-act{ width:100%; text-align:left; background:none; border:0;
  font:inherit; color:inherit; cursor:pointer; border-radius:6px;
  padding:.14rem .3rem; margin-left:-.3rem; }
.sched .r.sched-act:hover{ background:var(--hover); }
.sched .r.sched-act:focus-visible{ outline:2px solid var(--blue); outline-offset:1px; }
:root[data-theme="dark"] .sched .r.sched-act:focus-visible{ outline-color:var(--bluesub); }
.sched .sched-go{ margin-left:auto; font-size:clamp(.76rem,1.52vh,.88rem); font-weight:600;
  color:var(--blue); white-space:nowrap; }
:root[data-theme="dark"] .sched .sched-go{ color:var(--bluesub); }
.sched .r.sched-act:hover .sched-go{ text-decoration:underline; }
.forfeit{ margin-top:clamp(.3rem,.85vh,.6rem); background:var(--amber-bg); border:1px solid var(--amber-line);
  color:var(--amber-ink); border-radius:10px; padding:clamp(.42rem,1vh,.75rem) .85rem;
  font-size:clamp(.88rem,1.76vh,1.02rem); line-height:1.4; }
.oknote{ margin-top:clamp(.3rem,.85vh,.6rem); background:var(--green-bg); border:1px solid transparent;
  color:var(--green-ink); border-radius:10px; padding:clamp(.42rem,1vh,.75rem) .85rem;
  font-size:clamp(.88rem,1.76vh,1.02rem); }
/* Four inputs now, in a half-width column. Wrap rather than crush: a floor on the
   field width lets them fall to two rows instead of squeezing the date input
   below its intrinsic size, which is what pushed the row out of the card. */
.whatif .row{ display:flex; gap:.8rem; flex-wrap:wrap; }
.whatif .row .field{ min-width:7.25rem; }
.field{ display:flex; flex-direction:column; gap:.2rem; flex:1; }
.field label{ font-size:clamp(.78rem,1.56vh,.92rem); font-weight:600; color:var(--muted); }
.field input{ border:1px solid var(--rule); border-radius:8px; padding:clamp(.38rem,.9vh,.6rem) .55rem;
  font:inherit; font-size:clamp(.95rem,2vh,1.1rem); background:var(--canvas); color:var(--ink); width:100%; }
.wi-res{ margin-top:clamp(.4rem,1vh,.7rem); }
.wi-res .r{ display:flex; justify-content:space-between; align-items:baseline;
  padding:clamp(.2rem,.6vh,.35rem) 0; border-top:1px solid var(--rule); }
.wi-res .r .k{ color:var(--muted); font-size:clamp(.9rem,1.8vh,1.05rem); }
.wi-res .r .k em{ font-style:normal; display:block; font-size:clamp(.78rem,1.56vh,.92rem); }
.wi-res .r .val{ font-size:clamp(1.2rem,2.4vh,1.45rem); font-weight:700; }
.wi-res .r .val.pos{ color:var(--moss); } .wi-res .r .val.neg{ color:var(--accent); }

/* ---- Explanatory lede (non-dashboard pages) ---- */
.lede{ color:var(--muted); font-size:clamp(.88rem,1.76vh,1.02rem); line-height:1.5; max-width:78ch; }
.notice{ background:var(--amber-bg); border:1px solid var(--amber-line); color:var(--amber-ink);
  border-radius:10px; padding:.65rem .85rem; font-size:clamp(.88rem,1.76vh,1.02rem); line-height:1.45; }

/* ---- Tables (My Team / Forfeiture) ----
   PTO.sortable renders its table inside its own .card, so that card carries no
   padding here and the cell padding does the spacing instead. The card sizes to the
   table and the WRAPPER scrolls, so on a narrow screen the right-hand columns stay
   reachable instead of being clipped. */
.tbl-wrap{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
.tbl-wrap > .card{ padding:0; overflow:hidden; min-width:max-content; }
table{ width:100%; min-width:520px; border-collapse:collapse; }
th,td{ text-align:left; padding:.55rem .8rem; border-bottom:1px solid var(--rule);
  font-size:clamp(.9rem,1.8vh,1.04rem); white-space:nowrap; }
th{ font-size:clamp(.78rem,1.56vh,.92rem); font-weight:600; color:var(--muted); background:transparent; }
th.sortable{ cursor:pointer; user-select:none; }
th.sortable:hover{ color:var(--ink); }
th.sorted{ color:var(--accent); }
.arrow{ color:var(--accent); }
tbody tr:hover{ background:var(--canvas); }
tr:last-child td{ border-bottom:none; }
td.num{ text-align:right; font-variant-numeric:tabular-nums; }
td.name{ font-weight:600; }
td.name .you{ font-size:.72rem; color:var(--muted); margin-left:.4rem; font-weight:500; }
/* Status pills in table cells — the colour coding carried over from the previous
   production tables, which read faster down a long column than plain words. */
.pill{ display:inline-block; font-size:clamp(.74rem,1.48vh,.86rem); font-weight:600;
  padding:.14rem .55rem; border-radius:999px; white-space:nowrap; }
.pill.good,.pill.yes{ background:var(--green-bg); color:var(--green-ink); }
.pill.low{ background:var(--amber-bg); color:var(--amber-ink); }
.pill.over,.pill.bad{ background:var(--red-bg); color:var(--red-ink); }
.pill.no{ background:var(--track); color:var(--muted); }
.risk{ color:var(--accent); font-weight:600; }
.dash{ color:var(--muted); }

/* A short row of figures reads better content-sized than stretched across twelve
   columns — four tiles on a wide screen should not each be 450px of mostly air. */
.statstrip{ display:flex; flex-wrap:wrap; gap:var(--vgap); }
.statstrip > .card{ flex:1 1 auto; min-width:150px; max-width:260px; }
@media(max-width:640px){ .statstrip > .card{ min-width:calc(50% - var(--vgap)); max-width:none; } }
.empty{ padding:1.6rem; text-align:center; color:var(--muted); font-style:italic; }

/* ---- Filter buttons ---- */
.filters{ display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; }
.fbtn{ font-size:clamp(.8rem,1.6vh,.94rem); font-weight:600; border:1px solid var(--rule);
  background:var(--paper); color:var(--muted); padding:.4rem .8rem; border-radius:8px; cursor:pointer; }
.fbtn.active{ background:var(--blue); color:#fff; border-color:var(--blue); }
:root[data-theme="dark"] .fbtn.active{ color:#0F0D09; background:var(--bluesub); border-color:var(--bluesub); }
.fcount{ font-size:clamp(.82rem,1.64vh,.96rem); color:var(--muted); }

/* ---- Request page ----
   A form is a single column of reading, so it sits in a card of readable width
   rather than stretching its inputs the full width of a large screen. */
.req-page{ background:var(--paper); border:1px solid var(--rule); border-radius:var(--radius);
  box-shadow:var(--shadow); padding:clamp(.9rem,2vh,1.5rem) clamp(1rem,2vw,1.6rem);
  width:100%; max-width:760px; margin:0 auto; }
.req-page h2{ font-size:clamp(1.15rem,2.65vh,1.6rem); margin:0 0 .25rem; }
.req-sub{ color:var(--muted); font-size:clamp(.88rem,1.76vh,1.02rem); line-height:1.5; margin:0 0 1rem; }

/* ---- Request form / modal ---- */
.req-field{ display:flex; flex-direction:column; gap:.3rem; }
.req-field > span{ font-size:clamp(.78rem,1.56vh,.92rem); font-weight:600; color:var(--muted); }
.req-field > span em{ font-style:normal; opacity:.75; font-weight:400; }
.req-field input,.req-field select,.req-field textarea{ background:var(--canvas); border:1px solid var(--rule);
  border-radius:8px; padding:.55rem .65rem; color:var(--ink); font:inherit; width:100%; }
.req-field textarea{ resize:vertical; }
.req-row{ display:flex; gap:.85rem; } .req-row .req-field{ flex:1; }
.req-check{ display:flex; align-items:center; gap:.5rem; font-size:.88rem; cursor:pointer; }
.req-check input{ width:auto; margin:0; accent-color:var(--accent); }
.req-body{ display:flex; flex-direction:column; gap:.8rem; }
.req-actions{ display:flex; justify-content:flex-end; gap:.6rem; margin-top:1rem; align-items:center; }
.req-btn{ font-size:.85rem; font-weight:600; background:var(--accent); color:#fff; border:1px solid var(--accent);
  padding:.55rem 1.1rem; border-radius:8px; cursor:pointer; text-decoration:none; }
.req-btn.ghost{ background:transparent; color:var(--muted); border-color:var(--rule); }
.req-btn.urgent{ background:var(--red-ink); border-color:var(--red-ink); }
.req-btn:disabled{ opacity:.55; cursor:default; }
:root[data-theme="dark"] .req-btn{ color:#160c06; }
:root[data-theme="dark"] .req-btn.ghost{ color:var(--muted); }
.req-status{ margin-top:.7rem; font-size:.9rem; min-height:1rem; }
.req-status .req-err{ color:var(--accent); } .req-status .req-muted{ color:var(--muted); }
.to-warn{ border-radius:10px; padding:.65rem .85rem; font-size:.9rem; line-height:1.45;
  background:var(--amber-bg); color:var(--amber-ink); border:1px solid var(--amber-line); }
.req-success{ text-align:center; padding:1.2rem 0 .4rem; }
.req-success-icon{ width:48px; height:48px; border-radius:50%; background:var(--moss); color:#fff;
  font-size:1.4rem; display:flex; align-items:center; justify-content:center; margin:0 auto .8rem; }
:root[data-theme="dark"] .req-success-icon{ color:#0F0D09; }
.req-success h3{ font-size:1.2rem; margin-bottom:.35rem; }
.req-success p{ color:var(--muted); font-size:.94rem; margin-bottom:1rem; }
.req-success .req-actions{ justify-content:center; }
.req-modal{ position:fixed; inset:0; z-index:1000; display:flex; align-items:center; justify-content:center;
  background:rgba(20,16,10,.55); padding:1rem; }
.req-modal-card{ background:var(--paper); color:var(--ink); border:1px solid var(--rule); border-radius:14px;
  box-shadow:0 20px 60px rgba(0,0,0,.35); width:100%; max-width:460px; padding:1.2rem 1.3rem;
  max-height:90vh; overflow-y:auto; }
.req-modal-head{ display:flex; align-items:center; justify-content:space-between; margin-bottom:.9rem; }
.req-modal-head h3{ font-size:1.2rem; margin:0; }
.req-close{ background:none; border:none; font-size:1.5rem; line-height:1; color:var(--muted); cursor:pointer; }
.req-close:hover{ color:var(--ink); }
.req-myreq{ margin-top:1rem; padding-top:.9rem; border-top:1px solid var(--rule); }
.req-myreq-title{ font-size:clamp(.78rem,1.56vh,.92rem); font-weight:600; color:var(--muted); margin-bottom:.5rem; }
.req-modal-body{ display:flex; flex-direction:column; gap:.85rem; }
.req-modal-foot{ display:flex; justify-content:flex-end; gap:.6rem; margin-top:1.2rem; }
#req-notice:not(:empty){ margin-top:.2rem; }

/* ---- Service-team availability, shown inside the request modal ----
   Lived inline in index.html, which meant the calendar page's copy of the modal
   rendered it unstyled. Shared now, and on tokens so it themes with everything else. */
#timeoff{ padding-top:0; }
.to-section{ margin-top:.5rem; }
.to-grid{ display:grid; grid-template-columns:1fr 1fr; gap:1.25rem; align-items:start; }
@media(max-width:860px){ .to-grid{ grid-template-columns:1fr; } }
.to-card{ background:var(--paper); border:1px solid var(--rule); border-radius:var(--radius);
  box-shadow:var(--shadow); padding:1.15rem 1.3rem; }
.to-card-title{ font-size:clamp(.82rem,1.64vh,.96rem); font-weight:600; color:var(--muted); margin-bottom:.7rem; }
.to-head{ display:flex; align-items:center; justify-content:space-between; gap:1rem; margin-bottom:1rem; flex-wrap:wrap; }
.to-head .section-title{ margin-bottom:0; }
.to-field-row{ display:flex; gap:1rem; flex-wrap:wrap; }
.to-field{ display:flex; flex-direction:column; gap:.3rem; }
.to-field label{ font-size:clamp(.78rem,1.56vh,.92rem); font-weight:600; color:var(--muted); }
.to-field input{ background:var(--canvas); border:1px solid var(--rule); border-radius:8px;
  padding:.5rem .6rem; color:var(--ink); font:inherit; }
.to-result{ margin-top:1rem; }
.to-ok{ border-radius:10px; padding:.7rem .85rem; font-size:.9rem; line-height:1.5;
  background:var(--green-bg); color:var(--green-ink); }
.to-ok a, .to-warn a{ color:inherit; font-weight:600; }
.to-actions{ display:flex; gap:.5rem; flex-wrap:wrap; margin-top:.6rem; }
.to-btn{ font-size:.85rem; font-weight:600; border:1px solid var(--accent); background:var(--accent);
  color:#fff; padding:.45rem .8rem; border-radius:8px; cursor:pointer; text-decoration:none; }
.to-btn.ghost{ background:transparent; color:var(--accent); }
:root[data-theme="dark"] .to-btn{ color:#160c06; }
:root[data-theme="dark"] .to-btn.ghost{ color:var(--accent); background:transparent; }
.to-escalate{ margin-top:.6rem; font-size:.88rem; line-height:1.5; color:var(--ink); }
.to-daylist{ margin-top:.9rem; display:flex; flex-direction:column; gap:.35rem; }
.to-day{ display:flex; justify-content:space-between; align-items:center; gap:.75rem;
  padding:.5rem .7rem; border:1px solid var(--rule); border-radius:8px; font-size:.88rem; }
.to-day.cap{ border-color:var(--amber-line); background:var(--amber-bg); }
.to-day .cnt{ font-size:.82rem; color:var(--muted); text-align:right; }
.to-day.cap .cnt{ color:var(--amber-ink); }
.to-cal{ display:flex; flex-direction:column; max-height:440px; overflow:auto; }
.to-cal-row{ display:grid; grid-template-columns:auto 1fr auto; gap:.7rem; align-items:center;
  padding:.5rem .1rem; border-bottom:1px solid var(--rule); font-size:.9rem; }
.to-cal-row:last-child{ border-bottom:none; }
.to-dates{ font-size:.82rem; color:var(--muted); white-space:nowrap; }
.to-badge{ font-size:.74rem; font-weight:600; padding:.14rem .5rem; border-radius:999px; white-space:nowrap; }
.to-badge.pto{ background:var(--hover); color:var(--blue); }
.to-badge.ooo{ background:var(--track); color:var(--muted); }
.to-badge.svc{ background:var(--accent); color:#fff; margin-left:.35rem; }
:root[data-theme="dark"] .to-badge.pto{ color:var(--bluesub); }
:root[data-theme="dark"] .to-badge.svc{ color:#160c06; }
.to-muted{ color:var(--muted); font-style:italic; font-size:.92rem; }

/* ---- Vacation calendar ---- */
.cal-head{ display:flex; align-items:center; justify-content:space-between; gap:1rem; flex-wrap:wrap; }
.cal-title{ font-size:clamp(1.2rem,2.65vh,1.6rem); font-weight:700; letter-spacing:-.02em; min-width:11ch; }
.cal-nav{ display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; }
.cal-btn{ font-size:clamp(.8rem,1.6vh,.94rem); font-weight:600; background:var(--paper);
  border:1px solid var(--rule); color:var(--ink); padding:.42rem .75rem; border-radius:8px; cursor:pointer; }
.cal-btn:hover{ border-color:var(--muted); }
.cal-scope{ display:flex; align-items:center; gap:.4rem; font-size:clamp(.8rem,1.6vh,.94rem);
  color:var(--muted); cursor:pointer; white-space:nowrap; }
.cal-scope input{ width:auto; margin:0; accent-color:var(--accent); cursor:pointer; }
/* The whole month fits the screen. Week rows share the height left after the
   masthead, month header, legend, weekday strip and footer, and the renderer caps
   how many people it stacks per week to what that leaves room for — the rest
   collapse into a "+N" chip. Nothing scrolls. */
.cal-weeks{ border:1px solid var(--rule); border-radius:12px; background:var(--paper);
  box-shadow:var(--shadow); overflow:hidden; }
.cal-dow-row{ display:grid; grid-template-columns:repeat(7,1fr); border-bottom:1px solid var(--rule);
  background:var(--paper); }
.cal-dow{ font-size:clamp(.75rem,1.5vh,.88rem); font-weight:600; color:var(--muted); padding:.45rem; text-align:center; }
/* Everyone off in a week gets a row — a "+N more" hides exactly the information the
   page exists to show, so it is a last resort for an absurd week, not a layout tool.
   Rows take the height the screen can give them (the month needs only as many weeks
   as it touches, set by the renderer in --cal-weeks) and grow past it when a busy
   week needs more, so a quiet month fits and only a heavy one scrolls. The renderer
   reads --cal-lane/--cal-gap back out, so CSS and JS cannot drift. */
:root{ --cal-chrome:262px; --cal-weeks:6; --cal-lane:clamp(15px,1.8vh,19px); --cal-gap:3px; }
.cw{ position:relative; border-bottom:1px solid var(--rule);
  min-height:clamp(56px,calc((100vh - var(--cal-chrome)) / var(--cal-weeks)),170px); }
.cw:last-child{ border-bottom:none; }
.cw-bg{ position:absolute; inset:0; display:grid; grid-template-columns:repeat(7,1fr); }
.cw-bg > div{ border-right:1px solid var(--rule); }
.cw-bg > div:last-child{ border-right:none; }
.cw-bg > div.other{ background:var(--canvas); }
.cw-bg > div.today{ background:rgba(195,62,29,.07); }
:root[data-theme="dark"] .cw-bg > div.today{ background:rgba(224,104,47,.12); }
.cw-dates{ position:relative; display:grid; grid-template-columns:repeat(7,1fr); }
.cw-dates > div{ text-align:right; padding:4px 7px 0; font-size:clamp(.75rem,1.5vh,.88rem); color:var(--muted); }
.cw-dates > div.other{ opacity:.45; }
.cw-dates > div.today{ color:var(--accent); font-weight:700; }
.cw-bars{ position:relative; display:grid; grid-template-columns:repeat(7,1fr);
  grid-auto-rows:var(--cal-lane); gap:var(--cal-gap); padding:3px 4px 6px; }
/* stands in for the people a week has no room to list */
.cw-more{ min-width:0; font-size:.72rem; font-weight:600; padding:0 6px;
  line-height:var(--cal-lane); height:var(--cal-lane);
  border-radius:10px; color:var(--muted); background:var(--track); white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis; cursor:default; }
/* One source of truth for the request-type colours. The calendar bars and the
   legend swatches above them both read these, so a colour cannot be changed in
   one place and left stale in the other. */
:root{ --ev-pto:var(--blue); --ev-ooo:#6B6154; --ev-pat:#135F35; }
:root[data-theme="dark"]{ --ev-pto:var(--bluesub); --ev-ooo:#B2A99B; --ev-pat:var(--moss); }
/* Each type exposes its colour as --barc, so a whole day fills with it and a partial
   day can texture it without losing label contrast. */
.bar-ev{ --barc:var(--ev-pto); min-width:0; font-size:.75rem; padding:0 7px;
  line-height:var(--cal-lane); height:var(--cal-lane);
  border-radius:10px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; color:#fff; background:var(--barc); }
.bar-ev.ooo{ --barc:var(--ev-ooo); } .bar-ev.pat{ --barc:var(--ev-pat); }
:root[data-theme="dark"] .bar-ev{ color:#0F0D09; }
.bar-ev .svc{ opacity:.85; font-weight:700; }
/* Part of a day: keep the type fill so the label keeps its contrast, and add a faint,
   widely-spaced diagonal texture — enough to read as "not a whole day". */
.bar-ev.partial{ background-image:repeating-linear-gradient(135deg,
  rgba(255,255,255,.12) 0 6px, rgba(255,255,255,0) 6px 16px); }
:root[data-theme="dark"] .bar-ev.partial{ background-image:repeating-linear-gradient(135deg,
  rgba(0,0,0,.10) 0 6px, rgba(0,0,0,0) 6px 16px); }
/* Awaiting approval: the same type colour as an outline on the page colour, dashed,
   so it reads as planned rather than booked. The type stays recognizable and the
   label keeps its contrast, and the partial-day stripes are dropped because the
   hours are already in the label. */
.bar-ev.pending, :root[data-theme="dark"] .bar-ev.pending{ background:var(--paper);
  background-image:none; color:var(--barc); border:1.5px dashed var(--barc);
  line-height:calc(var(--cal-lane) - 3px); }
.bar-ev .pt{ font-weight:600; margin-left:.15rem; opacity:.95; }
/* Legend swatches carry the same fill as the bars they stand for, and the same
   rounded-rect shape, so the key reads as a sample of the calendar rather than a
   separate set of marks. Without the per-type fills these inherit .dot's
   currentColor and all three come out the legend's muted grey. */
.legend .dot.pto, .legend .dot.ooo, .legend .dot.pat, .legend .k-partial{
  width:14px; height:10px; border-radius:3px; display:inline-block; }
.legend .dot.pto{ background:var(--ev-pto); }
.legend .dot.ooo{ background:var(--ev-ooo); }
.legend .dot.pat{ background:var(--ev-pat); }
.legend .k-pending{ width:14px; height:10px; border-radius:3px; display:inline-block;
  border:1.5px dashed var(--ev-pto); background:var(--paper); }
.legend .k-partial{ background:var(--ev-pto);
  background-image:repeating-linear-gradient(135deg, rgba(255,255,255,.45) 0 3px, rgba(255,255,255,0) 3px 7px); }
:root[data-theme="dark"] .legend .k-partial{
  background-image:repeating-linear-gradient(135deg, rgba(0,0,0,.30) 0 3px, rgba(0,0,0,0) 3px 7px); }

/* On-call rotations from AlertOps. A tinted strip with a solid left edge, so it reads
   as a different kind of thing from time off, which is always a filled pill. The three
   colours stay clear of the PTO blue, out-of-office brown and paternity green. */
:root{ --oc1:#6D3FA0; --oc2:#0E6E78; --oc3:#A3263B; }
:root[data-theme="dark"]{ --oc1:#C3A6E8; --oc2:#6FCFD6; --oc3:#F08A9B; }
@media (prefers-color-scheme: dark){ :root:not([data-theme="light"]){ --oc1:#C3A6E8; --oc2:#6FCFD6; --oc3:#F08A9B; } }
.oc1{ --occ:var(--oc1); } .oc2{ --occ:var(--oc2); } .oc3{ --occ:var(--oc3); }
.bar-oc{ min-width:0; font-size:.75rem; padding:0 7px 0 5px; line-height:var(--cal-lane); height:var(--cal-lane);
  border-radius:4px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; cursor:default;
  color:var(--ink); background:color-mix(in srgb, var(--occ) 13%, var(--paper));
  border-left:3px solid var(--occ); }
.bar-oc .oc-tag{ font-weight:700; color:var(--occ); margin-right:.35rem; }
.legend .oc-pick{ display:flex; align-items:center; gap:.4rem 1rem; flex-wrap:wrap; margin-left:auto; }
.legend .oc-pick[hidden]{ display:none; }
.legend .oc-pick{ gap:.4rem; }
.oc-lbl{ font-weight:600; color:var(--ink); margin-right:.15rem; }
/* Each rotation is a toggle pill. Off it is an outline in the legend's grey; on it
   takes the same tint and colour as its strips on the calendar, so the pill reads as
   a sample of what it adds. The checkbox stays in the label for keyboard and screen
   readers and is only hidden from view. */
.oc-opt{ position:relative; display:flex; align-items:center; gap:.4rem; cursor:pointer; white-space:nowrap;
  padding:.16rem .62rem .16rem .5rem; border:1px solid var(--rule); border-radius:4px;
  background:var(--paper); color:var(--muted); font-weight:600; line-height:1.35;
  transition:background-color .12s, border-color .12s, color .12s; }
.oc-opt:hover{ border-color:var(--occ); color:var(--ink); }
.oc-opt input{ position:absolute; opacity:0; width:1px; height:1px; margin:0; pointer-events:none; }
.legend .oc-opt .oc-k{ width:8px; height:8px; border-radius:2px; display:inline-block;
  background:transparent; border:1.5px solid var(--occ); }
.oc-opt:has(input:checked){ background:color-mix(in srgb, var(--occ) 13%, var(--paper));
  border-color:var(--occ); color:var(--ink); }
.legend .oc-opt:has(input:checked) .oc-k{ background:var(--occ); }
.oc-opt:has(input:focus-visible){ outline:2px solid var(--ink); outline-offset:2px; }

/* A strip a lead may act on. The affordance is deliberately quiet — the calendar
   is read-first, and most bars on screen are not actionable, so a loud treatment
   would misrepresent how much of the grid is clickable. */
.bar-ev.actionable{ cursor:pointer; }
.bar-ev.actionable:hover{ filter:brightness(1.12); }
.bar-ev.actionable:focus-visible{ outline:2px solid var(--ink); outline-offset:1px; }

/* ---- Manage a team member's time off ---- */
.mng-who{ font-weight:600; font-size:1.05rem; margin-bottom:.5rem; }
.mng-item{ border:1px solid var(--rule); border-radius:10px; padding:.7rem .8rem; margin-bottom:.6rem; }
.mng-item:last-child{ margin-bottom:0; }
.mng-item-head{ display:flex; align-items:baseline; justify-content:space-between; gap:.6rem; margin-bottom:.45rem; }
.mng-actions{ display:flex; gap:.5rem; justify-content:flex-end; margin-top:.5rem; flex-wrap:wrap; }
/* Read-only rows carry no inputs or buttons, so they do not need the padding
   that made room for them. */
.mng-item.read{ padding:.5rem .8rem; }
.mng-item.read .mng-item-head{ margin-bottom:0; }

/* ---- "Your upcoming time off" list (markup injected by pto-calc.js) ---- */
.myreq-list{ display:flex; flex-direction:column; gap:.45rem; }
.myreq-row{ display:flex; align-items:center; justify-content:space-between; gap:.75rem;
  padding:.55rem .75rem; border:1px solid var(--rule); border-radius:10px; background:var(--paper); }
.myreq-row.done{ opacity:.55; }
.myreq-when{ font-weight:600; font-size:.92rem; }
.myreq-meta{ font-size:.78rem; color:var(--muted); margin-top:.12rem; }
.myreq-badge{ display:inline-block; font-size:.66rem; font-weight:700; letter-spacing:.04em;
  text-transform:uppercase; padding:.1rem .42rem; border-radius:999px; margin-left:.4rem; }
.myreq-badge.approved{ background:var(--green-bg); color:var(--green-ink); }
.myreq-badge.pending{ background:var(--amber-bg); color:var(--amber-ink); }
.myreq-cancel{ font-size:.78rem; font-weight:600; border:1px solid var(--rule); background:transparent;
  color:var(--accent); padding:.35rem .7rem; border-radius:8px; cursor:pointer; white-space:nowrap; }
.myreq-cancel:hover{ background:var(--accent); color:#fff; }
.myreq-cancel[disabled]{ opacity:.5; cursor:default; }
.myreq-empty{ color:var(--muted); font-style:italic; font-size:.9rem; }

/* ---- Short viewports ----
   The arrangement is the same at every screen size — same rows, same order, same
   card widths. A shallow screen is handled purely by scale. Nothing reflows. */

/* ---- Phones ---- */
@media (max-width:640px){
  /* brand row carries the theme toggle; actions and picker follow below */
  .mh-in{ position:relative; padding:.55rem 1rem; gap:.5rem; }
  .mh-logo{ height:26px; } .mh-title{ font-size:1rem; }
  .mh-l{ width:calc(100% - 46px); }
  #theme-btn{ position:absolute; top:.55rem; right:1rem; }
  .mh-r{ width:100%; gap:.4rem; }
  #nav{ flex:1 1 100%; }
  .picker{ flex:1 1 150px; } .picker select{ flex:1; min-width:0; }
  .greet{ gap:.3rem; } .greet h1{ font-size:1.4rem; }
  .greet .meta{ gap:.6rem; font-size:.78rem; }
  /* the breakdown stacks under the balance, so its rule belongs on top */
  .hero-row{ gap:0; }
  .hero-tab{ width:100%; min-width:0; border-left:none; padding-left:0;
    border-top:1px solid var(--blueline); padding-top:.5rem; margin-top:.55rem; }
  .hero-big{ font-size:2.6rem; }
  /* per-day hours are the first thing to go when the row gets narrow */
  .toff-detail{ display:none; }
  .whatif .row{ flex-wrap:wrap; }
  .whatif .row .field:last-child{ flex:1 1 100%; }
  .meter i{ height:20px; }
  .accr-foot b{ font-size:1rem; }
  .req-row{ flex-wrap:wrap; } .req-row .req-field{ flex:1 1 100%; }
  .cal-head{ gap:.5rem; }
  .cw{ min-height:70px; }
  .container{ padding-left:1rem; padding-right:1rem; }
}
/* Once the grid has stacked, the four small figures still read better two-up than as
   four full-width bands. After the rule that sends stacked cards to full width, so it
   applies to the tiles only — the hero and stat cards stay full width. */
@media (max-width:700px){
  .tile{ grid-column:span 6; }
  /* half-width tiles are narrow enough that the status word wraps on a 360px phone
     and drags its row taller, so size it off the width available */
  .tile-status .v{ font-size:clamp(.95rem,4.3vw,1.15rem); }
}
