/* ============================================================
   SPOTLESS UNIFIED CLEANER PWA — app shell + component kit
   Loads AFTER ../staff/fonts.css and ../staff/brand.css.
   brand.css already defines: --blue --blue-d --green --green-d
   --ink --gold --danger --bg --surface --line --grad --display --body
   We layer the tab shell + kit + R2 accessible-action split on top.
   ============================================================ */

:root{
  /* R2 — split the action color: brand blue fails AA for small text.
     --action is used for all text-bearing controls / links < 18px. */
  --action:#1F5FA8;
  --blue-dd:#17457C;
  /* light stop darkened #3D93E0→#368CDB so white AND the white→pale-green gradient
     numerals stay ≥3:1 (AA large) against the lightest corner of every blue hero */
  --grad-blue:linear-gradient(125deg,#368CDB 0%,#1F5FA8 100%);
  --grad-green:linear-gradient(125deg,#7CC24A 0%,#4E9A2A 100%);

  /* semantic (+tint) — darkened for WCAG AA */
  --success:#4E9A2A; --success-bg:#EAF5E0;
  --warn:#E08A1E;    --warn-bg:#FCF1DE;
  --danger:#B93A2E;  --danger-bg:#FBE7E4;
  --info:#2F86D6;    --info-bg:#E5F0FB;
  /* QA1: dedicated ink tokens (decouple status text from the interactive --action color).
     --info-ink #1F5FA8 on --info-bg = 5.5:1 (AA); --warn-ink #8A5000 on --warn-bg = 7.1:1 (AA). */
  --info-ink:#1F5FA8;
  --warn-ink:#8A5000;

  /* surfaces — warm/cool canvas, premium blue-tinted cards */
  --app-bg:#F4F7FB; --surface-2:#F7FAFD; --surface-sunk:#EAF0F7; --overlay:rgba(18,38,62,.55);

  /* text */
  --ink-2:#48607A; --ink-3:#8397AD; --on-blue:#FFFFFF; --on-blue-soft:#D6E7F8;

  /* lines */
  --line-strong:#CBD8E6; --focus:#1F5FA8;

  /* grade scale (pass 7.75 / floor 6.0) — darkened to pass AA at list size on white */
  --grade-gold:#8A6100; --grade-pass:#4E9A2A; --grade-mid:#B4600A; --grade-low:#C0392B;

  /* space / radius / tap */
  --page-x:16px; --card-pad:18px; --gap:12px; --tap:56px; --tap-2:48px;
  --r-pill:999px;
  /* radius scale — zero ad-hoc corner values; everything maps to one of these */
  --r-xs:10px; --r-sm:12px; --r-md:14px; --r-lg:16px; --r-xl:20px; --r-hero:22px; --r-sheet:24px;

  /* elevation (blue-tinted) */
  --e-1:0 1px 2px rgba(19,38,62,.06),0 1px 3px rgba(19,38,62,.05);
  --e-2:0 4px 12px rgba(19,38,62,.08),0 2px 4px rgba(19,38,62,.05);
  --e-3:0 12px 28px rgba(19,38,62,.14),0 4px 8px rgba(19,38,62,.06);
  --e-nav:0 -2px 16px rgba(19,38,62,.08);
  --e-blue:0 8px 20px rgba(47,134,214,.32);
  --e-green:0 8px 20px rgba(111,178,59,.30);

  /* motion */
  --t-instant:90ms; --t-fast:140ms; --t-base:220ms; --t-slow:380ms; --tab-slide:8px;
  --e-out:cubic-bezier(.22,.61,.36,1); --e-soft:cubic-bezier(.34,1.2,.64,1); --e-std:cubic-bezier(.4,0,.2,1);
  --safe-b:env(safe-area-inset-bottom,0px);
  --tabbar-h:76px; /* 2026 "bigger" pass: 64→76 (owner ask) — .app padding + toast offset follow automatically */

  /* font aliases (brand.css uses --body; blueprint uses --sans) */
  --sans:var(--body);
}

/* rem-based, respects OS text scaling */
html{font-size:100%}
*{box-sizing:border-box}
body{
  margin:0;font-family:var(--sans);color:var(--ink);background:var(--app-bg);
  line-height:1.45;-webkit-font-smoothing:antialiased;
  -webkit-tap-highlight-color:transparent;overscroll-behavior-y:none;
}
[hidden]{display:none!important}

/* logical props only — RTL native */
html[dir=rtl] .row,
html[dir=rtl] .card__head,
html[dir=rtl] .seg,
html[dir=rtl] .tabbar .rail{ }
.notranslate{unicode-bidi:isolate}
.scale{direction:ltr;font-variant-numeric:tabular-nums}   /* numeric axis stays LTR + non-jitter in RTL */
bdi{unicode-bidi:isolate}

/* focus (a11y) */
:focus-visible{outline:3px solid var(--focus);outline-offset:2px;border-radius:inherit}
:focus:not(:focus-visible){outline:none}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important;
  }
}

/* ── screens (login vs app) ── */
.screen{display:none}
.screen.active{display:block}

/* ── app shell ── */
.app{
  min-height:100dvh;
  padding-bottom:calc(var(--tabbar-h) + var(--safe-b) + 8px);
}
.tab-panel{
  display:none;
  padding:0 var(--page-x) 22px;
  animation:none;
}
.tab-panel.active{
  display:block;
  animation:panelIn var(--t-base) var(--e-out);
}
@keyframes panelIn{
  from{opacity:0;transform:translateX(var(--dir,0)) translateY(6px)}
  to{opacity:1;transform:none}
}

/* ── topbar / greeting ── */
.topbar{
  display:flex;align-items:center;gap:11px;
  padding:calc(env(safe-area-inset-top,0px) + 10px) var(--page-x) 10px;
  position:sticky;top:0;z-index:20;
  background:rgba(244,247,251,.9);backdrop-filter:blur(10px);
}
.topbar .lg{width:30px;height:30px;border-radius:8px;flex:none}
.topbar .nm{font-family:var(--display);font-weight:800;font-size:16px;letter-spacing:-.01em}
.topbar .topbtn{width:48px;height:48px;border:none;background:none;border-radius:12px;cursor:pointer;
  color:var(--action);display:grid;place-items:center;position:relative;flex:none}
.topbar .topbtn .ic{width:24px;height:24px}
.topbar .topbtn:active{transform:scale(.92)}
.topbtn__badge{position:absolute;top:5px;inset-inline-end:5px;min-width:17px;height:17px;padding:0 4px;
  border-radius:9px;background:var(--danger);color:#fff;font-size:11px;font-weight:800;
  display:grid;place-items:center;line-height:1;border:2px solid var(--app-bg)}

/* gradient greeting header */
.hello{
  background:var(--grad-blue);color:var(--on-blue);
  border-radius:var(--r-hero);padding:22px 20px;margin:4px 0 16px;
  box-shadow:var(--e-blue);position:relative;overflow:hidden;
}
.hello:before{content:"";position:absolute;inset:0;
  background:radial-gradient(600px 240px at 88% -20%,rgba(255,255,255,.22),transparent 60%)}
.hello__hi{position:relative;font-family:var(--display);font-weight:800;font-size:26px;line-height:1.05;letter-spacing:-.02em}
.hello__sub{position:relative;opacity:.94;font-size:14px;margin-top:4px}

/* ── cards ── */
.card{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);
  box-shadow:var(--e-2);padding:var(--card-pad);margin:0 0 14px;
}
.card--accent{border-inline-start:4px solid var(--action)}
.card--green{background:var(--success-bg);border-color:#CBE6B4}
.card__head{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.card__icon{width:30px;height:30px;flex:none;display:grid;place-items:center;color:var(--action)}
.card__title{font-family:var(--display);font-weight:800;font-size:18px;letter-spacing:-.01em;display:inline-flex;align-items:center;gap:7px}
/* gold-tinted trophy (home score card + Me hero tier) */
.ic--gold{color:var(--grade-gold)}
/* page title — the strong per-tab heading (replaces the weak card__title tab headers) */
.page-title{font-family:var(--display);font-weight:800;font-size:22px;letter-spacing:-.02em;line-height:1.1;margin:14px 0 12px}
.card__meta{margin-inline-start:auto;font-size:12px;color:var(--ink-2);font-weight:700} /* AA at <18px */
.muted{color:var(--ink-2)}
.tiny{font-size:12px}

/* ── buttons ── */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  font-family:var(--sans);font-weight:800;font-size:16px;
  min-height:var(--tap);padding:0 20px;border-radius:var(--r-lg);border:1.5px solid transparent;
  cursor:pointer;text-decoration:none;transition:transform var(--t-fast) var(--e-soft);
  touch-action:manipulation;width:100%;
}
.btn .ic{width:22px;height:22px;flex:none}
.btn--primary{background:var(--blue);color:#fff;font-size:18px;box-shadow:var(--e-blue)} /* R2: label >=18/700 on blue OK */
.btn--hero{background:var(--grad-blue);color:#fff;font-size:18px;box-shadow:var(--e-blue)}
.btn--go{background:var(--grad-green);color:#fff;text-shadow:0 1px 1px rgba(20,60,10,.25);box-shadow:var(--e-green)} /* white on #4E9A2A AA-safe at 700/>=18px */
.btn--danger{background:var(--danger);color:#fff}
.btn--ghost{background:#fff;color:var(--action);border-color:var(--line-strong)}
.btn--sm{min-height:var(--tap-2);font-size:15px;padding:0 14px;width:auto}
.btn--xl{min-height:72px;font-size:20px;border-radius:var(--r-xl)}
/* ghost text-link button (dispute / low-emphasis) */
.btn--link{background:none;border:none;box-shadow:none;color:var(--action);width:auto;min-height:var(--tap-2);font-size:15px;margin-top:6px}
.btn--link .ic{width:18px;height:18px;color:var(--ink-2)}
.dispute-btn{opacity:.9}
.btn:active{transform:scale(.97)}
.btn[disabled]{opacity:.55;pointer-events:none}
.btn-row{display:flex;gap:12px;margin-top:12px}
.btn-row .btn{flex:1}

/* pressable */
.pressable{transition:transform var(--t-fast) var(--e-soft)}
.pressable:active{transform:scale(.96)}

/* ── chips ── */
.chips{display:flex;flex-wrap:wrap;gap:8px;margin:8px 0}
.chip{
  display:inline-flex;align-items:center;gap:6px;
  min-height:var(--tap-2);padding:0 14px;border-radius:var(--r-pill);
  font-size:14px;font-weight:700;cursor:pointer;
  background:#fff;border:1.5px solid var(--line-strong);color:var(--ink);
}
.chip.on{background:var(--info-bg);border-color:var(--blue);color:var(--action)}
.chip--done{background:var(--success-bg);border-color:#BCD9AD;color:#3B6D11;cursor:default}
.chip--off{background:var(--surface-sunk);border-color:var(--line);color:var(--ink-2)}
.chip[disabled]{opacity:.45;pointer-events:none}
.seg{display:flex;gap:6px;background:var(--surface-sunk);border-radius:14px;padding:5px;margin:0 0 14px}
.seg button{
  flex:1;min-height:var(--tap-2);border:none;background:none;border-radius:10px;
  font-size:14px;font-weight:800;color:var(--ink-2);cursor:pointer;
}
.seg button.on{background:#fff;color:var(--action);box-shadow:var(--e-1)}

/* ── rows (schedule / hours / photos list) ── */
.row{
  display:flex;align-items:flex-start;gap:12px;
  padding:12px 4px;border-top:1px solid var(--line);
}
.row:first-child{border-top:none}
.row__dot{width:8px;align-self:stretch;border-radius:4px;flex:none;min-height:36px}
.row__lead{flex:none;text-align:center;min-width:52px;font-weight:800;font-size:13px;color:var(--ink-2)}
.row__main{flex:1;min-width:0}
.row__title{font-weight:800;font-size:15px}
.row__meta{font-size:13px;color:var(--ink-2);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.row__val{margin-inline-start:auto;font-weight:800;text-align:end;white-space:nowrap}
/* The job sheet the website writes onto a booked shift — what the customer asked for, read at the
   door. It used to arrive as one 500-character string in .row__meta above, which is nowrap +
   ellipsis: everything past the first few words was literally not on the screen. Two columns, the
   answer allowed to wrap, and the rows that decide whether a cleaner gets it right — the address,
   what they typed, the add-ons they paid for — carrying their own weight. */
.jobsheet{margin-top:12px;border:1px solid var(--line,#e6e8ea);border-radius:12px;overflow:hidden}
.jobsheet__r{display:grid;grid-template-columns:minmax(0,116px) minmax(0,1fr);gap:2px 12px;padding:8px 12px;font-size:13px;line-height:1.45}
.jobsheet__r+.jobsheet__r{border-top:1px solid var(--line,#e6e8ea)}
.jobsheet__r>span{color:var(--ink-2);min-width:0;overflow-wrap:anywhere}
.jobsheet__r>b{min-width:0;overflow-wrap:anywhere;font-weight:700}
.jobsheet__r--key{background:rgba(47,134,214,.06)}
.jobsheet__r--key>b{font-weight:800}
@media(max-width:380px){.jobsheet__r{grid-template-columns:1fr;gap:0}}
.row--today{background:linear-gradient(90deg,rgba(47,134,214,.08),transparent);border-radius:12px}
.row--today .row__lead{color:var(--action)}
.row--dim{opacity:.55}
.row__lead-h{color:var(--action);font-weight:800;margin-top:3px;font-variant-numeric:tabular-nums}
/* week hours chip */
.weekchip{display:flex;align-items:center;gap:10px;background:var(--info-bg);border:1px solid #BFDCF5;
  border-radius:14px;padding:12px 16px;margin:0 0 14px;font-weight:800;color:var(--action)}
.weekchip b{margin-inline-start:auto;font-family:var(--display);font-size:20px}
.thumb{width:52px;height:52px;border-radius:12px;object-fit:cover;flex:none;background:var(--surface-sunk)}

/* status chips inside rows */
.st{display:inline-flex;align-items:center;gap:5px;font-size:12.5px;font-weight:800;
  padding:5px 10px;border-radius:var(--r-pill);margin-top:5px}
/* status glyphs live in ::before so they follow dir (RTL-safe), never hard-coded LTR in JS */
.st::before{font-weight:900;line-height:1}
.st--ask{background:var(--warn-bg);color:var(--warn-ink)}    /* M4: darkened amber → AA */
.st--wait{background:var(--warn-bg);color:var(--warn-ink)}
.st--wait::before{content:"\23F3"}                           /* ⏳ */
.st--ok{background:var(--success-bg);color:#3B6D11}
.st--ok::before{content:"\2713"}                             /* ✓ */
.st--no{background:var(--surface-sunk);color:var(--ink-2)}
.st--no::before{content:"\2715"}                             /* ✕ */
.st--done{background:var(--info-bg);color:var(--info-ink)}   /* QA1: own token, AA on --info-bg */
/* office review of a photo (mirrors Connecteam manager fields) */
.st--redo{background:var(--warn-bg);color:var(--warn-ink)}
.st--redo::before{content:"\21BB"}                           /* ↻ */

/* ── hero (score) ── */
.hero{
  background:var(--grad-blue);color:#fff;border-radius:var(--r-hero);padding:20px;
  box-shadow:var(--e-blue);display:flex;align-items:center;gap:16px;
}
.hero__avatar{width:60px;height:60px;border-radius:50%;object-fit:cover;background:rgba(255,255,255,.25);flex:none}
.hero__body{flex:1;min-width:0}
.hero__name{font-family:var(--display);font-weight:800;font-size:20px;letter-spacing:-.01em}
.hero__score{font-family:var(--display);font-weight:800;font-size:34px;line-height:1;font-variant-numeric:tabular-nums}
.hero__denom{font-size:16px;opacity:.85;font-weight:700}
.hero__tier{display:inline-flex;align-items:center;gap:6px;font-size:13px;font-weight:800;
  background:rgba(255,255,255,.18);border:1px solid rgba(255,255,255,.34);border-radius:var(--r-pill);padding:5px 11px;margin-top:6px}
.hero__meta{font-size:13px;opacity:.94;margin-top:8px}
.hero--empty{background:var(--surface);color:var(--ink);border:1px solid var(--line)}

/* grade badge + progress bar */
.grade{font-family:var(--display);font-weight:800;font-variant-numeric:tabular-nums}
.grade--gold{color:var(--grade-gold)} .grade--pass{color:var(--grade-pass)}
.grade--mid{color:var(--grade-mid)}   .grade--low{color:var(--grade-low)}
.grade--dim{color:var(--ink-2)}                              /* M5: small dim "—" → AA */
.grade--dim.grade--xl{color:var(--ink-3)}                    /* XL variant can stay lighter */
.grade--xl{font-size:44px}
/* /10 denominator — de-emphasised so the number is the hero (FIX 9) */
.grade__denom{font-size:.5em;opacity:.55;font-weight:800;margin-inline-start:1px}
.grade--lg{font-size:32px}
.u-center{text-align:center}
.bar{height:9px;border-radius:6px;background:var(--surface-sunk);overflow:hidden;margin-top:8px}
.bar > i{display:block;height:100%;border-radius:6px;background:var(--grad-green);transform-origin:left;transition:transform var(--t-slow) var(--e-out)}
.pill{display:inline-flex;align-items:center;gap:5px;font-size:12.5px;font-weight:800;
  padding:5px 11px;border-radius:var(--r-pill);background:var(--surface-sunk);color:var(--ink-2)}
.pill--go{background:var(--success-bg);color:#3B6D11}
.pill--wait{background:var(--warn-bg);color:var(--warn-ink)}  /* M5: AA */
.pill--auto{background:var(--surface-sunk);color:var(--ink-2)}
.pill--owner{background:var(--warn-bg);color:var(--warn-ink)}

/* ── on-shift banner ── */
.onshift{background:var(--success-bg);border:1px solid #BCD9AD;border-radius:var(--r-xl);padding:18px;margin-bottom:14px}
.onshift__t{font-family:var(--display);font-weight:800;font-size:18px;color:#2F5A12}
.onshift__timer{font-family:var(--display);font-weight:800;font-size:38px;color:var(--green-d);letter-spacing:.02em;font-variant-numeric:tabular-nums}
/* live pip (replaces 🟢) */
.live-pip{display:inline-block;width:11px;height:11px;border-radius:50%;background:var(--green);vertical-align:middle;
  box-shadow:0 0 0 0 rgba(111,178,59,.55);animation:pulse 1.8s infinite}

/* ── forms ── */
.field{margin-bottom:14px}
.field > label{display:block;font-weight:800;font-size:14px;margin-bottom:6px}
.input,.select{
  width:100%;min-height:var(--tap);font-size:17px;font-family:var(--sans);
  padding:0 14px;border:1.5px solid var(--line-strong);border-radius:14px;background:#fff;color:var(--ink);
}
.select{appearance:none;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%231F5FA8' stroke-width='2.5'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat:no-repeat;background-position:right 14px center;padding-inline-end:40px}
html[dir=rtl] .select{background-position:left 14px center}
.input:focus,.select:focus{border-color:var(--action)}
.help{font-size:13px;color:var(--ink-2);margin-top:6px}
.err{color:var(--danger);font-weight:700;font-size:14px;margin-top:8px}

/* ── login ── */
.login{max-width:420px;margin:0 auto;padding:calc(env(safe-area-inset-top,0px) + 40px) 22px 40px;
  min-height:100dvh;display:flex;flex-direction:column;justify-content:center}
.login__logo{width:78px;height:78px;border-radius:20px;box-shadow:var(--e-3);margin:0 auto 18px;display:block}
.login h1{font-family:var(--display);font-weight:800;font-size:30px;text-align:center;margin:0 0 4px;letter-spacing:-.02em}
.login__sub{text-align:center;color:var(--ink-2);margin:0 0 22px}
.login .btn{margin-top:6px}
.login__privacy{text-align:center;font-size:12.5px;color:var(--ink-3);margin-top:16px}
.login__lang{margin-top:22px;text-align:center}
.login__lang .select{max-width:220px;margin:8px auto 0;text-align:center}

/* ── bottom tab bar (keystone) ── */
.tabbar{
  position:fixed;inset-inline:0;bottom:0;z-index:40;
  background:rgba(255,255,255,.97);backdrop-filter:blur(12px);
  border-top:1px solid var(--line);box-shadow:var(--e-nav);
  padding-bottom:var(--safe-b);
}
.tabbar .rail{display:flex}
.tab{
  flex:1;min-height:var(--tabbar-h);min-width:48px;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  border:none;background:none;cursor:pointer;color:var(--ink-2); /* AA: inactive tab label >=4.5:1 */
  padding:8px 2px 6px;position:relative;font-family:var(--sans);
  transition:color var(--t-fast) var(--e-std);
}
.tab .ic{width:26px;height:26px}
.tab-label{font-size:12px;font-weight:800;letter-spacing:-.01em}
.tab[aria-selected="true"]{color:var(--action)}
.tab[aria-selected="true"] .ic{transform:translateY(-1px)}
/* duotone active state: the .duo silhouette (currentColor @ fill-opacity .18)
   cross-fades in behind the stroke. Group opacity animates 0→1; the 18% tint
   itself lives on the fill-opacity attribute in the SVG. The global
   prefers-reduced-motion rule collapses the fade to instant. */
.tab .ic .duo{opacity:0;transition:opacity .25s var(--e-std)}
.tab[aria-selected="true"] .ic .duo{opacity:1}
.tab:active{transform:scale(.94)}
.badge{
  position:absolute;top:6px;inset-inline-start:calc(50% + 8px);
  min-width:18px;height:18px;padding:0 4px;border-radius:9px;
  background:var(--danger);color:#fff;font-size:11px;font-weight:800;
  display:grid;place-items:center;line-height:1;
}
.badge--dot{min-width:10px;width:10px;height:10px;padding:0;inset-inline-start:calc(50% + 10px)}
.tab .live-dot{position:absolute;top:8px;inset-inline-start:calc(50% + 9px);width:9px;height:9px;border-radius:50%;
  background:var(--green);box-shadow:0 0 0 0 rgba(111,178,59,.6);animation:pulse 1.8s infinite}
@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(111,178,59,.55)}70%{box-shadow:0 0 0 8px rgba(111,178,59,0)}100%{box-shadow:0 0 0 0 rgba(111,178,59,0)}}

/* ── sheet / modal ── */
.scrim{position:fixed;inset:0;background:var(--overlay);z-index:60;opacity:0;transition:opacity var(--t-base) var(--e-std)}
.scrim.open{opacity:1}
.sheet{
  position:fixed;inset-inline:0;bottom:0;z-index:61;
  background:var(--surface);border-radius:var(--r-sheet) var(--r-sheet) 0 0;
  padding:8px var(--page-x) calc(20px + var(--safe-b));max-height:88dvh;overflow:auto;
  transform:translateY(100%);transition:transform var(--t-base) var(--e-out);box-shadow:var(--e-3);
}
.sheet.open{transform:none}
.sheet__grip{width:44px;height:5px;border-radius:3px;background:var(--line-strong);margin:8px auto 14px}
.sheet__title{font-family:var(--display);font-weight:800;font-size:20px;margin:0 0 4px}
.sheet__photo{width:100%;border-radius:16px;position:relative;margin:10px 0}
.sheet__photo img{width:100%;border-radius:16px;display:block}
.spot{position:absolute;width:26px;height:26px;margin:-13px 0 0 -13px;border-radius:50%;
  border:3px solid var(--danger);background:rgba(185,58,46,.25);box-shadow:0 0 0 2px #fff;
  animation:ping 1.3s var(--e-out) 2}
@keyframes ping{0%{transform:scale(.4);opacity:0}40%{opacity:1}100%{transform:scale(1);opacity:1}}

/* ── toast ── */
.toast-wrap{position:fixed;left:0;right:0;bottom:calc(var(--tabbar-h) + var(--safe-b) + 12px);z-index:70;
  display:flex;flex-direction:column;align-items:center;gap:8px;pointer-events:none;padding:0 16px}
.toast{
  background:var(--ink);color:#fff;font-weight:700;font-size:14px;
  padding:12px 18px;border-radius:14px;box-shadow:var(--e-3);max-width:420px;
  display:flex;align-items:center;gap:9px;
  transform:translateY(12px);opacity:0;transition:all var(--t-base) var(--e-out);
}
.toast .ic{width:18px;height:18px;flex:none}
.toast.show{transform:none;opacity:1}
.toast--ok{background:var(--success)}
.toast--bad{background:var(--danger)}

/* ── skeletons ── */
.skel{background:linear-gradient(100deg,var(--surface-sunk) 30%,#F3F7FC 50%,var(--surface-sunk) 70%);
  background-size:200% 100%;animation:shimmer 1.2s linear infinite;border-radius:10px}
@keyframes shimmer{to{background-position:-200% 0}}
.sk--line{height:14px;margin:8px 0}
.sk--hero{height:96px;border-radius:22px;margin-bottom:14px}
.sk--row{height:56px;margin:10px 0;border-radius:14px}

/* ── empty / error ── */
.empty{text-align:center;padding:28px 16px;color:var(--ink-2)}
.empty .big{font-size:30px;margin-bottom:6px;line-height:1}
.empty .big .ic--xl{width:38px;height:38px;color:var(--ink-3)}
.empty--error .big{color:var(--danger)}
.empty--error .big .ic--xl{color:var(--danger)}

/* ── offline banner ── */
.offline{background:var(--warn-bg);color:var(--warn-ink);border:1px solid #F0D8A8;border-radius:14px; /* QA1: unified amber ink */
  padding:11px 14px;font-size:13.5px;font-weight:700;margin-bottom:12px;display:flex;gap:8px;align-items:center}

/* ── P1-D: photo-gate banner on the on-shift cards — same amber family as .offline
   (--warn-ink on --warn-bg = 7.1:1, AA). Static (no animation) → reduced-motion safe. ── */
.gatebar{background:var(--warn-bg);color:var(--warn-ink);border:1px solid #F0D8A8;border-radius:14px;
  padding:11px 14px;font-size:13.5px;font-weight:800;margin-top:10px;display:flex;gap:8px;align-items:center;text-align:start}
.gatebar .ic{flex:none}

/* ── P2-F: type-to-filter box above the site <select> (logical margins → RTL-safe) ── */
.site-search{margin-bottom:8px}
.site-search::-webkit-search-cancel-button{-webkit-appearance:none}

/* ── pull to refresh ── */
.ptr{height:0;overflow:hidden;display:grid;place-items:center;color:var(--action);transition:height var(--t-fast) var(--e-std)}
.ptr .spin{width:22px;height:22px;border:3px solid var(--surface-sunk);border-top-color:var(--action);border-radius:50%;animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* menu rows (Me) */
.menu{background:var(--surface);border:1px solid var(--line);border-radius:20px;box-shadow:var(--e-2);overflow:hidden;margin-bottom:14px}
.menu__row{display:flex;align-items:center;gap:14px;min-height:var(--tap);padding:0 16px;
  border-top:1px solid var(--line);background:none;border-inline:none;border-bottom:none;
  width:100%;text-align:start;font-size:16px;font-weight:700;color:var(--ink);cursor:pointer;font-family:var(--sans)}
.menu__row:first-child{border-top:none}
/* Me tiles — 2026 refresh: superellipse feel (38% radius on the 34px square),
   soft two-stop tint gradients per hue, glyph optically centered by the grid */
/* NOTE 2026 pass: background REMOVED here — this 2-class selector used to outweigh the
   1-class .ic--tint-* hue tiles and painted every tile gray (the silent killer of the
   last redesign). Hue gradients + shadows live on .ic--tint-*. Also scoped to the
   DIRECT child tile (>) so the chevron's svg.ic no longer inherits tile padding/bg. */
.menu__row > .ic{width:34px;height:34px;border-radius:38%;
  display:grid;place-items:center;color:#fff;flex:none;padding:6px}
.menu__row .ic svg,.menu__row .ic .ic{width:20px;height:20px;background:none;padding:0;border-radius:0}
/* per-row accent tiles — 2026 VIVID pass: full two-stop brand-hue gradients (same stops
   as the #g-* SVG paint-servers), WHITE glyph, soft matching drop shadow. iOS-Settings
   premium, not pastel. Icons are decorative — the row label carries the meaning (AA). */
.ic--tint-blue{background:linear-gradient(135deg,#4AA3E8,#1F5FA8);color:#fff;box-shadow:0 4px 10px rgba(47,134,214,.35)}
.ic--tint-green{background:linear-gradient(135deg,#7CC24A,#4E9A2A);color:#fff;box-shadow:0 4px 10px rgba(78,154,42,.32)}
.ic--tint-indigo{background:linear-gradient(135deg,#A78BFA,#6D4ACF);color:#fff;box-shadow:0 4px 10px rgba(109,74,207,.32)}
.ic--tint-amber{background:linear-gradient(135deg,#FFC24B,#E8890C);color:#fff;box-shadow:0 4px 10px rgba(232,137,12,.32)}
.ic--tint-teal{background:linear-gradient(135deg,#4FD1C5,#0E9488);color:#fff;box-shadow:0 4px 10px rgba(14,148,136,.32)}
.ic--tint-slate{background:linear-gradient(135deg,#94A3B8,#475569);color:#fff;box-shadow:0 4px 10px rgba(71,85,105,.28)}
.ic--tint-danger{background:linear-gradient(135deg,#F87171,#C0392B);color:#fff;box-shadow:0 4px 10px rgba(192,57,43,.32)}
.menu__row .chev{margin-inline-start:auto;color:var(--ink-3)}
.menu__row .me-pill{margin-inline-start:auto}
.me-unread{background:var(--danger);color:#fff;font-size:12px;font-weight:800;min-width:20px;height:20px;
  border-radius:10px;display:grid;place-items:center;padding:0 5px}
.menu__row.is-danger{color:var(--danger)}
/* chevrons flip in RTL */
html[dir=rtl] .menu__row .chev,html[dir=rtl] .doc-body .chev{transform:scaleX(-1);display:inline-block}
/* inline icon sizes */
.ic--xs{width:15px;height:15px}
.ic--sm{width:20px;height:20px}
.ic--xl{width:34px;height:34px}

/* ── add to home screen card ── */
.a2hs{position:relative;border:1px dashed var(--blue);background:var(--surface-2)}
.a2hs .card__head{margin-bottom:6px}
.a2hs__x{position:absolute;top:10px;inset-inline-end:10px;width:30px;height:30px;border:none;background:none;
  border-radius:8px;color:var(--ink-3);display:grid;place-items:center;cursor:pointer}
.a2hs__x .ic{width:18px;height:18px}
.a2hs p .ic{vertical-align:middle;color:var(--action)}

/* confetti (pass) */
.confetti{position:fixed;inset:0;pointer-events:none;z-index:80;overflow:hidden}
.confetti i{position:absolute;top:-12px;width:9px;height:14px;border-radius:2px;animation:fall 1.6s var(--e-out) forwards}
@keyframes fall{to{transform:translateY(105vh) rotate(540deg);opacity:0}}

/* count-up score number */
.countup{font-variant-numeric:tabular-nums}

/* don't mirror these glyphs in RTL */
html[dir=rtl] .no-mirror{transform:none}

/* ── messages (chat) ── */
.chat-list{max-height:52dvh;overflow:auto;padding:4px 0 10px;display:flex;flex-direction:column;gap:8px}
.ch-b{max-width:80%;padding:9px 13px;border-radius:16px;font-size:14.5px;line-height:1.4;word-break:break-word}
.ch-b.me{align-self:flex-end;background:var(--info-bg);color:var(--ink);border-end-end-radius:5px}
.ch-b.them{align-self:flex-start;background:var(--surface-sunk);color:var(--ink);border-end-start-radius:5px}
.ch-t{font-size:11px;color:var(--ink-2);margin-top:4px}
.chat-inrow{display:flex;gap:8px;margin-top:10px}
.chat-inrow .input{flex:1}
.chat-inrow .btn{width:auto;flex:none;padding:0 16px}
.doc-body{font-size:14px;line-height:1.55;color:var(--ink);margin-top:8px}
.doc-body ul{margin:4px 0 4px 18px}

/* ── training exam ── */
.exam-prog{display:flex;align-items:center;gap:10px;position:sticky;top:0;z-index:2;
  background:var(--surface);padding:8px 0 12px;font-weight:800;color:var(--ink-2)}
.exam-prog b{color:var(--action)}
.exam-card{padding:16px}
.exam-q{font-weight:800;font-size:15.5px;line-height:1.4;margin-bottom:4px}
.exam-opts{display:flex;flex-direction:column;gap:8px;margin-top:10px}
.exam-opt{display:flex;align-items:center;gap:12px;min-height:var(--tap);width:100%;text-align:start;
  padding:8px 14px;border-radius:14px;border:1.5px solid var(--line-strong);background:#fff;
  font-size:15px;font-weight:700;color:var(--ink);cursor:pointer;font-family:var(--sans);
  transition:border-color var(--t-fast) var(--e-std),background var(--t-fast) var(--e-std)}
.exam-opt.on{border-color:var(--blue);background:var(--info-bg);color:var(--action)}
.exam-box{width:24px;height:24px;flex:none;border-radius:50%;border:2px solid var(--line-strong);
  display:grid;place-items:center;color:#fff}
.exam-box.sq{border-radius:7px}
.exam-opt.on .exam-box{background:var(--blue);border-color:var(--blue)}
.exam-opt.on .exam-box .ic{width:14px;height:14px}

/* ── chevrons: real SVG, optically centred + RTL-mirrored ── */
.menu__row .chev,.doc-body .chev,.row .chev{display:inline-flex;align-items:center;color:var(--ink-3)}
.menu__row .chev .ic,.row .chev .ic{width:20px;height:20px}
html[dir=rtl] .chev{transform:scaleX(-1)}

/* ── task chips with a check box (adopts the exam-option pattern) ── */
.chip__box{width:20px;height:20px;flex:none;border-radius:6px;border:2px solid var(--line-strong);
  display:grid;place-items:center;color:#fff}
.chip__box .ic{width:13px;height:13px}
.chip--done .chip__box{background:var(--success);border-color:var(--success)}
/* day-off chips: the ✕ marker is a CSS-revealed SVG, no text glyph */
.chip--day .chip__x{width:0;overflow:hidden;transition:width var(--t-fast) var(--e-std);display:inline-flex;align-items:center;color:var(--ink-2)}
.chip--day .chip__x .ic{width:14px;height:14px}
.chip--day.chip--off .chip__x{width:14px;margin-inline-start:4px}

/* ── shift row (schedule) — explicit radius so the focus ring matches the shape ── */
.shiftrow{border-radius:var(--r-md);padding-inline:6px}
.row__dot{min-height:22px}

/* ── FEATURE A — confirm zone (pinned "needs your answer") ── */
.cz{border:1px solid #BFDCF5;background:var(--info-bg)}
.cz-row{padding:12px 0;border-top:1px solid rgba(31,95,168,.14)}
.cz-row:first-of-type{border-top:none}
.cz-when{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.cz-site{font-weight:800;font-size:15px;margin:2px 0 8px}
.cz-act{display:flex;gap:10px}
.cz-act .btn{flex:1}

/* ── FEATURE C — wins card ── */
.wins{margin-top:14px}
.win-row{display:flex;align-items:center;gap:12px;padding:9px 0;border-top:1px solid var(--line);font-weight:700;font-size:14.5px}
.win-row:first-of-type{border-top:none}
.win-ic{width:34px;height:34px;flex:none;border-radius:10px;background:var(--warn-bg);color:var(--grade-gold);display:grid;place-items:center;padding:7px}

/* ── FEATURE D — timesheet weekly grouping ── */
.hours-wk{margin-bottom:8px}
.hours-wk__head{display:flex;align-items:center;gap:8px;margin:14px 0 2px;font-weight:800;color:var(--ink-2);font-size:13px}
.hours-wk__sub{margin-inline-start:auto;color:var(--action);font-family:var(--display);font-size:16px}
.hours-total{border-top:2px solid var(--line-strong);margin-top:6px}

/* ── docs list tile ── */
.doc-tile{width:34px;height:34px;flex:none;border-radius:10px;display:grid;place-items:center;padding:7px}

/* ── FIX 7 — designed photo-grade loading skeleton (not a bare spinner) ── */
.grade-load{padding:24px 18px}
.gl-num{width:120px;height:52px;border-radius:var(--r-md);margin:0 auto 14px}
.gl-img{width:100%;height:180px;border-radius:16px;margin:0 auto 16px}
.grade-load b{display:block;margin-top:2px}

/* ═══════════ ENGAGEMENT: Updates / Recognitions / Events / Rewards ═══════════ */
.pill--sample{background:var(--surface-sunk);color:var(--ink-2);border:1px dashed var(--line-strong)}
.chip--on{background:var(--danger-bg);border-color:var(--danger);color:var(--danger)}
.feed-card{margin-bottom:10px}
.feed-card.is-new{border-inline-start:3px solid var(--action)}
.feed-card .card__head{align-items:flex-start;gap:8px}
.feed-meta{display:flex;align-items:center;gap:6px;flex-wrap:wrap;font-size:12.5px;color:var(--ink-2);font-weight:600} /* AA: --ink-3 was 3.0:1 */
.feed-meta .ic{color:var(--ink-2)}
.dot-new{width:9px;height:9px;border-radius:50%;background:var(--action);flex:none;margin-top:5px}
.feed-full{padding-top:2px}
.feed-h3{font-size:15px;font-weight:800;margin:16px 0 8px;color:var(--ink)}
.cmt{padding:9px 0;border-top:1px solid var(--line);font-size:14px;line-height:1.5}
.cmt:first-child{border-top:none}
.cmt-h{font-size:12px;font-weight:800;color:var(--ink-2);margin-bottom:2px} /* AA: was --ink-3 */
/* recognitions — badge-forward: the emoji IS the hero of the card */
.recog{display:flex;gap:14px;align-items:flex-start;margin-bottom:10px}
.recog-badge{font-size:46px;line-height:1;flex:none;filter:drop-shadow(0 1px 2px rgba(0,0,0,.12))}
.recog-main{flex:1;min-width:0}
/* events */
.event{margin-bottom:10px}
.event .feed-meta{margin-top:4px}
.rsvp-row{display:flex;flex-direction:column;gap:8px;border-top:1px solid var(--line);padding-top:10px}
.rsvp-btns{display:flex;gap:8px}
.rsvp{flex:1;min-height:44px;border-radius:12px;border:1.5px solid var(--line-strong);background:var(--surface);
  font-weight:800;font-size:14px;color:var(--ink-2);cursor:pointer;font-family:var(--sans);transition:all var(--t-fast) var(--e-std)}
.rsvp.on{color:#fff}
.rsvp--going.on{background:var(--success);border-color:var(--success)}
.rsvp--maybe.on{background:var(--gold);border-color:var(--gold)}
.rsvp--no.on{background:var(--ink-3);border-color:var(--ink-3)}
/* rewards */
.rewards-bal{display:flex;align-items:center;gap:16px;margin-bottom:6px}
.rewards-bal__ic{width:52px;height:52px;flex:none;border-radius:14px;background:var(--success-bg);display:grid;place-items:center;color:#3B6D11}
.rewards-bal__ic .ic{width:30px;height:30px}
.rewards-bal__n{font-size:34px;font-weight:900;line-height:1;color:var(--ink)}
.reward{display:flex;align-items:center;gap:12px;margin-bottom:10px}
.reward-main{flex:1;min-width:0}
.reward-side{flex:none;display:flex;flex-direction:column;align-items:flex-end;gap:6px}
.reward-cost{font-size:13px;font-weight:800;color:var(--action);white-space:nowrap}
.reward-side .btn{width:auto;padding:0 14px}

/* ═══════════ UPDATES v2 — themed banner cards + inline like + NEW pulse ═══════════ */
/* Theme banner map — the SAME ids + gradients as the admin composer (UTHEMES in /admin:
   ocean | brand | fresh | sunset | plum; "none" = no banner). The banner is a decorative
   strip on a white card (mirrors the admin phone preview) so text stays var(--ink) → AA. */
.uban{height:52px;margin:calc(-1*var(--card-pad)) calc(-1*var(--card-pad)) 14px;
  border-radius:calc(var(--r-xl) - 1px) calc(var(--r-xl) - 1px) 0 0}
.uban--ocean {background:linear-gradient(135deg,#2F86D6,#2568B8)}
.uban--brand {background:linear-gradient(135deg,#2F86D6,#6FB23B)}
.uban--fresh {background:linear-gradient(135deg,#6FB23B,#4E8F26)}
.uban--sunset{background:linear-gradient(135deg,#E67E22,#E6A23C)}
.uban--plum  {background:linear-gradient(135deg,#7B3FA0,#C2185B)}
/* the detail sheet reuses the banner on its header card */
.upd-hero{border:1px solid var(--line);background:var(--surface);border-radius:var(--r-lg);padding:14px 16px;margin-bottom:12px;overflow:hidden}
.upd-hero .uban{margin:-14px -16px 12px;border-radius:calc(var(--r-lg) - 1px) calc(var(--r-lg) - 1px) 0 0}
.upd-hero .card__title{font-size:19px}
/* soft "NEW" pulse on the unread dot (killed by the global reduced-motion rule) */
.dot-new{animation:dotPulse 2s var(--e-std) infinite}
@keyframes dotPulse{0%,100%{box-shadow:0 0 0 0 rgba(31,95,168,.35)}50%{box-shadow:0 0 0 6px rgba(31,95,168,0)}}
/* inline actions row on an updates list card */
.feed-actions{display:flex;align-items:center;gap:8px;margin-top:10px;flex-wrap:wrap}
.feed-actions .feed-meta{margin-inline-start:auto}
.chip--mini{min-height:36px;padding:0 12px;font-size:13px}
.chip--like .ic{color:var(--danger)}
.chip--like.chip--on .ic{fill:currentColor}

/* ── office review note (MY GRADES) — quoted manager feedback ── */
.mgr-note{margin:10px 0 0;padding:9px 12px;border-inline-start:3px solid var(--line-strong);
  background:var(--surface-2);border-radius:0 10px 10px 0;font-size:14px;line-height:1.5;color:var(--ink-2);text-align:start}
html[dir=rtl] .mgr-note{border-radius:10px 0 0 10px}

/* ═══════════ EMPLOYEE RICHNESS ROUND — store / time off / my tasks / motion overhaul ═══════════
   Everything animated here is killed by the global prefers-reduced-motion rule at the top. */

/* staggered card entrance — .anim-in is added by showTab()/openApp() on SECTION ENTRY only and
   removed right after the run, so later re-renders never replay it (admin QA lesson) */
.tab-panel.anim-in>*{animation:cardIn var(--t-slow) var(--e-out) both}
.tab-panel.anim-in>*:nth-child(2){animation-delay:45ms}
.tab-panel.anim-in>*:nth-child(3){animation-delay:90ms}
.tab-panel.anim-in>*:nth-child(4){animation-delay:135ms}
.tab-panel.anim-in>*:nth-child(5){animation-delay:180ms}
.tab-panel.anim-in>*:nth-child(6){animation-delay:225ms}
.tab-panel.anim-in>*:nth-child(7){animation-delay:270ms}
.tab-panel.anim-in>*:nth-child(n+8){animation-delay:300ms}
@keyframes cardIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* bottom-nav active pill (glow behind the icon) + badge pulse */
.tab .ic,.tab .tab-label{position:relative;z-index:1}
.tab::before{content:"";position:absolute;top:5px;left:50%;width:46px;height:30px;border-radius:15px;
  background:var(--info-bg);opacity:0;transform:translateX(-50%) scale(.55);
  transition:opacity var(--t-fast) var(--e-std),transform var(--t-base) var(--e-soft)}
.tab[aria-selected="true"]::before{opacity:1;transform:translateX(-50%) scale(1)}
.badge,.topbtn__badge,.me-unread{animation:badgeGlow 2.4s var(--e-std) infinite}
@keyframes badgeGlow{0%,100%{box-shadow:0 0 0 0 rgba(185,58,46,.35)}50%{box-shadow:0 0 0 5px rgba(185,58,46,0)}}

/* stronger per-tab heading (type hierarchy pass) */
.page-title{font-size:24px}

/* home quick-action gradient card (the Connecteam "FORM" card) */
.qcard{width:100%;display:flex;align-items:center;gap:14px;background:var(--grad-blue);color:#fff;
  border:none;border-radius:var(--r-xl);padding:16px;box-shadow:var(--e-blue);cursor:pointer;
  text-align:start;margin:0 0 14px;font-family:var(--sans);position:relative;overflow:hidden}
.qcard::before{content:"";position:absolute;inset:0;
  background:radial-gradient(420px 160px at 90% -30%,rgba(255,255,255,.25),transparent 60%)}
.qcard>*{position:relative}
.qcard__ic{width:46px;height:46px;border-radius:13px;background:rgba(255,255,255,.18);
  border:1px solid rgba(255,255,255,.28);display:grid;place-items:center;flex:none}
.qcard__ic .ic{width:24px;height:24px}
.qcard__txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.qcard__txt b{font-size:16px;font-family:var(--display);letter-spacing:-.01em}
.qcard__txt span{font-size:13px;opacity:.92}
.qcard .chev{color:rgba(255,255,255,.85)}

/* recognition moment on Home — warm gold, badge-forward */
.recog-home{display:flex;align-items:center;gap:14px;background:linear-gradient(120deg,#FFF8E8,#FCF0D2);border-color:#EFDCA6}
.recog-home .recog-badge{font-size:34px}
.recog-home .card__title{font-size:16px}
.recog-home .chev{margin-inline-start:auto;color:var(--ink-3)}
.recog-main{flex:1;min-width:0}

/* Me — sectioned menu */
.menu-sec{font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-2);margin:18px 6px 8px}

/* ── rewards STORE ── */
.rw-bal{display:flex;align-items:center;gap:14px;background:var(--grad-blue);color:#fff;border-radius:var(--r-hero);
  padding:18px;box-shadow:var(--e-blue);margin:12px 0;position:relative;overflow:hidden}
.rw-bal::before{content:"";position:absolute;inset:0;
  background:radial-gradient(420px 160px at 88% -30%,rgba(255,255,255,.22),transparent 60%)}
.rw-bal>*{position:relative}
.rw-bal__ic{width:52px;height:52px;flex:none;border-radius:14px;background:rgba(255,255,255,.18);
  border:1px solid rgba(255,255,255,.3);display:grid;place-items:center;color:#fff}
.rw-bal__ic .ic{width:30px;height:30px}
.rw-bal__n{font-family:var(--display);font-size:38px;font-weight:800;line-height:1;font-variant-numeric:tabular-nums}
.rw-bal__pts{margin-inline-start:auto;font-size:13px;font-weight:800;opacity:.92;align-self:flex-end}
.store-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
.store-tile{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--e-1);
  padding:10px;display:flex;flex-direction:column;gap:8px}
.store-art{position:relative;height:86px;border-radius:var(--r-md);display:grid;place-items:center;color:#fff}
.store-art .store-glyph{font-size:38px;font-weight:900;font-family:var(--display);line-height:1;
  text-shadow:0 1px 2px rgba(0,0,0,.18)}
.store-val{position:absolute;top:6px;inset-inline-end:6px;background:rgba(255,255,255,.94);color:var(--ink);
  font-size:12px;font-weight:800;border-radius:8px;padding:2px 7px;font-family:var(--display)}
.store-name{font-weight:800;font-size:14px;line-height:1.25;flex:1}
.store-cost{display:inline-flex;align-items:center;gap:5px;font-weight:800;font-size:13px;color:var(--grade-gold)}
.store-cost .ic{color:var(--grade-gold)}
.store-tile.is-locked .store-art{filter:grayscale(.45);opacity:.7}
.store-tile.is-locked .store-name{color:var(--ink-2)}
.store-need{display:flex;flex-direction:column;gap:4px}
.store-need .tiny{color:var(--ink-2);font-weight:700}

/* ── time off ── */
.pol-row{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin:14px 0}
.pol-card{background:var(--surface);border:1.5px solid var(--line-strong);border-radius:var(--r-lg);
  padding:12px 6px;text-align:center;cursor:pointer;font-weight:800;font-size:12.5px;color:var(--ink);
  display:flex;flex-direction:column;gap:6px;align-items:center;justify-content:center;min-height:88px;font-family:var(--sans)}
.pol-card .pol-emoji{font-size:26px;line-height:1}
.pol-card.on{border-color:var(--blue);background:var(--info-bg);color:var(--action)}
.st--deny{background:var(--danger-bg);color:var(--danger)}
.st--deny::before{content:"\2715"}

/* ── my tasks ── */
.qt-row{display:flex;align-items:flex-start;gap:12px;padding:12px 2px;border-top:1px solid var(--line);
  transition:opacity var(--t-base) var(--e-std)}
.qt-row:first-child{border-top:none}
.qt-row.qt--done{opacity:.62}
.qt-check{width:34px;height:34px;flex:none;margin-top:1px;border-radius:50%;border:2px solid var(--line-strong);
  background:#fff;color:#fff;display:grid;place-items:center;cursor:pointer;padding:0;position:relative}
.qt-check::after{content:"";position:absolute;inset:-8px}       /* invisible hit extension → 50px tap */
.qt-check .ic{width:17px;height:17px}
.qt-check.on{background:var(--success);border-color:var(--success);animation:popIn .32s var(--e-soft)}
@keyframes popIn{0%{transform:scale(.55)}60%{transform:scale(1.18)}100%{transform:scale(1)}}
.qt-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;background:none;border:none;
  text-align:start;cursor:pointer;padding:0;font-family:var(--sans);color:var(--ink)}
.qt-title{position:relative;font-weight:800;font-size:15px;align-self:flex-start}
.qt-title::after{content:"";position:absolute;inset-inline:0;top:52%;height:2px;background:var(--ink-2);
  border-radius:1px;transform:scaleX(0);transform-origin:left center;transition:transform var(--t-base) var(--e-out)}
html[dir=rtl] .qt-title::after{transform-origin:right center}
.qt--done .qt-title{color:var(--ink-2)}
.qt--done .qt-title::after{transform:scaleX(1)}
.qt-due{display:inline-flex;align-items:center;gap:5px;font-size:12.5px;font-weight:700;color:var(--ink-2)}
.qt-due.is-over{color:var(--danger)}
.qt-note{font-size:13px;color:var(--ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}
.qt-alldone{display:flex;align-items:center;gap:8px;background:var(--success-bg);color:#3B6D11;
  border:1px solid #BCD9AD;border-radius:14px;padding:11px 14px;font-weight:800;font-size:14px;margin-bottom:12px}

/* ═══════════ MICRO-INTERACTIONS — 2026 (transform/opacity only, 60fps) ═══════════
   One-shot classes are applied by animOnce() in the app script and removed on
   animationend (+ fallback timeout). Everything below is killed by the global
   prefers-reduced-motion rule at the top of this file (duration → .001ms).      */

/* 1 — tab tap pop: springy scale layered over the duotone cross-fade.
   translateY(-1px) is baked in so the active-tab lift doesn't snap at the end. */
.tab .ic.icon-pop{animation:iconPop .28s cubic-bezier(.34,1.56,.64,1)}
@keyframes iconPop{
  0%{transform:translateY(-1px) scale(1)}
  45%{transform:translateY(-1px) scale(1.18)}
  100%{transform:translateY(-1px) scale(1)}
}

/* 2 — camera shutter pulse: quick squeeze + overshoot on capture */
.shutter-pop{animation:shutterPop .24s var(--e-soft)}
@keyframes shutterPop{
  0%{transform:scale(1)}
  35%{transform:scale(.92)}
  75%{transform:scale(1.08)}
  100%{transform:scale(1)}
}

/* 3 — heart burst: heart springs in + 4 currentColor dots fly out radially (like only) */
.heart-pop{animation:heartPop .42s cubic-bezier(.34,1.56,.64,1)}
@keyframes heartPop{
  0%{transform:scale(.2)}
  55%{transform:scale(1.25)}
  100%{transform:scale(1)}
}
.burst{position:absolute;width:0;height:0;pointer-events:none}   /* JS anchors it on the heart's centre */
.burst i{position:absolute;left:-2px;top:-2px;width:4px;height:4px;
  border-radius:50%;background:currentColor;opacity:0;
  animation:burstDot .42s var(--e-out) forwards}
@keyframes burstDot{
  0%{opacity:.85;transform:translate(0,0) scale(1)}
  100%{opacity:0;transform:translate(var(--bx,0),var(--by,-14px)) scale(.4)}
}

/* 4 — check draw-on: the tick strokes itself inside the existing popIn.
   Path length ≈22.3 viewBox units → dash 24. Class removal restores a full stroke. */
.check-draw svg.ic path{stroke-dasharray:24;stroke-dashoffset:24;
  animation:checkDraw .32s var(--e-out) .05s forwards}
@keyframes checkDraw{to{stroke-dashoffset:0}}

/* 5 — gift wiggle: small rock when the redeem-confirm sheet opens (symmetric → RTL-safe) */
.gift-wiggle{animation:giftWiggle .36s var(--e-std) .15s;transform-origin:50% 78%}
@keyframes giftWiggle{
  0%{transform:rotate(0)}
  25%{transform:rotate(-8deg)}
  60%{transform:rotate(8deg)}
  100%{transform:rotate(0)}
}

/* 6 — bell ring: damped 3-swing from the top-centre pivot on notifications success */
.bell-ring{animation:bellRing .6s var(--e-std);transform-origin:50% 14%}
@keyframes bellRing{
  0%{transform:rotate(0)}
  18%{transform:rotate(14deg)}
  42%{transform:rotate(-11deg)}
  66%{transform:rotate(6deg)}
  84%{transform:rotate(-3deg)}
  100%{transform:rotate(0)}
}

/* 7 — Me-menu tile squish: only the 34px tile compresses; the row + 44px tap target
   are untouched. Release springs back via the soft-overshoot bezier. */
.menu__row .ic{transition:transform var(--t-fast) var(--e-soft)}
.menu__row:active .ic{transform:scale(.9)}

/* 8 — badge pop: scale-in with overshoot when a badge value increases / dot appears */
.badge-pop{animation:badgePop .32s cubic-bezier(.34,1.56,.64,1)}
@keyframes badgePop{
  0%{transform:scale(0)}
  70%{transform:scale(1.15)}
  100%{transform:scale(1)}
}

/* ═══════════ 2026 VIVID GRADIENT PASS — color + presence (geometry untouched) ═══════════
   Hue system (mirrors the #g-* SVG paint-servers injected after <body>):
   blue #4AA3E8→#1F5FA8 · green #7CC24A→#4E9A2A · sky #5BC8F5→#2F86D6 ·
   amber #FFC24B→#E8890C · pink #FF8FB1→#E84393 · violet #A78BFA→#6D4ACF ·
   teal #4FD1C5→#0E9488 · slate #94A3B8→#475569.
   White glyphs on vivid tiles are decorative-plus-label: the text label next to each
   tile stays AA. All motion below rides existing transforms/opacity → the global
   prefers-reduced-motion rule collapses it. */

/* ── BOTTOM TAB BAR — the headline change. Active tab = vivid gradient squircle chip
   with a colored glow; the duotone icon inside turns WHITE (silhouette at .18 white
   adds depth); label stays brand-blue 800 (AA). Inactive tabs keep the slate stroke.
   The chip fades/scales in per tab via the existing ::before transition. ── */
.tab::before{top:4px;width:47px;height:31px;border-radius:15.5px}
#tab-home::before    {background:linear-gradient(135deg,#4AA3E8,#1F5FA8);box-shadow:0 4px 12px rgba(47,134,214,.42)}
#tab-schedule::before{background:linear-gradient(135deg,#A78BFA,#6D4ACF);box-shadow:0 4px 12px rgba(109,74,207,.40)}
#tab-clock::before   {background:linear-gradient(135deg,#7CC24A,#4E9A2A);box-shadow:0 4px 12px rgba(78,154,42,.40)}
#tab-photos::before  {background:linear-gradient(135deg,#FFC24B,#E8890C);box-shadow:0 4px 12px rgba(232,137,12,.40)}
#tab-me::before      {background:linear-gradient(135deg,#4FD1C5,#0E9488);box-shadow:0 4px 12px rgba(14,148,136,.40)}
.tab .ic{transition:color var(--t-fast) var(--e-std)}
.tab[aria-selected="true"] .ic{color:#fff}

/* ── vivid gradient icon tile (gtile) — home cards, sheet headers ── */
.gtile{width:30px;height:30px;flex:none;border-radius:10px;display:inline-grid;place-items:center;color:#fff}
.gtile .ic{width:18px;height:18px}
.gtile--blue  {background:linear-gradient(135deg,#4AA3E8,#1F5FA8);box-shadow:0 4px 10px rgba(47,134,214,.35)}
.gtile--green {background:linear-gradient(135deg,#7CC24A,#4E9A2A);box-shadow:0 4px 10px rgba(78,154,42,.32)}
.gtile--sky   {background:linear-gradient(135deg,#5BC8F5,#2F86D6);box-shadow:0 4px 10px rgba(47,134,214,.32)}
.gtile--amber {background:linear-gradient(135deg,#FFC24B,#E8890C);box-shadow:0 4px 10px rgba(232,137,12,.32)}
.gtile--pink  {background:linear-gradient(135deg,#FF8FB1,#E84393);box-shadow:0 4px 10px rgba(232,67,147,.32)}
.gtile--violet{background:linear-gradient(135deg,#A78BFA,#6D4ACF);box-shadow:0 4px 10px rgba(109,74,207,.32)}
.gtile--teal  {background:linear-gradient(135deg,#4FD1C5,#0E9488);box-shadow:0 4px 10px rgba(14,148,136,.32)}
.gtile--slate {background:linear-gradient(135deg,#94A3B8,#475569);box-shadow:0 4px 10px rgba(71,85,105,.28)}
/* sheet titles host a gtile now — flex keeps the tile + text on one baseline-ish row */
.sheet__title{display:flex;align-items:center;gap:10px}

/* ── gradient-stroke utilities — CSS stroke:url(#g-*) beats the currentColor
   presentation attribute; children inherit the paint server ── */
.ic--g-blue{stroke:url(#g-blue)}   .ic--g-green{stroke:url(#g-green)} .ic--g-sky{stroke:url(#g-sky)}
.ic--g-amber{stroke:url(#g-amber)} .ic--g-pink{stroke:url(#g-pink)}   .ic--g-violet{stroke:url(#g-violet)}
.ic--g-teal{stroke:url(#g-teal)}   .ic--g-slate{stroke:url(#g-slate)}

/* ── Me menu tiles — slightly rounder; vivid gradients come from .ic--tint-*. A tile
   that forgot its tint class falls back to the brand-blue gradient (the :not() keeps
   this rule off tinted tiles entirely, so no specificity fight with .ic--tint-*). ── */
.menu__row > :where(.ic):not([class*="ic--tint-"]){background:linear-gradient(135deg,#4AA3E8,#1F5FA8)}
.menu__row > .ic{border-radius:40%;color:#fff}

/* ── key-moment tiles: "Area done" camera (Photos hue) + Rewards balance coin (amber) +
   wins trophies (amber) — white glyph on the vivid tile in each case ── */
.qcard__ic{background:linear-gradient(135deg,#FFC24B,#E8890C);border:none;box-shadow:0 4px 12px rgba(0,0,0,.20)}
.rw-bal__ic{background:linear-gradient(135deg,#FFC24B,#E8890C);border:none;box-shadow:0 6px 14px rgba(180,96,10,.45)}
.win-ic{background:linear-gradient(135deg,#FFC24B,#E8890C);color:#fff;border-radius:11px;box-shadow:0 4px 10px rgba(232,137,12,.30)}

/* ── empty states — alive, not gray: the icon sits on a soft vivid tile ── */
.empty .big{width:62px;height:62px;margin:0 auto 12px;border-radius:20px;display:grid;place-items:center;
  background:linear-gradient(135deg,#5BC8F5,#2F86D6);color:#fff;box-shadow:0 6px 14px rgba(47,134,214,.30)}
.empty .big .ic--xl{width:32px;height:32px;color:#fff}
.empty .big--green {background:linear-gradient(135deg,#7CC24A,#4E9A2A);box-shadow:0 6px 14px rgba(78,154,42,.28)}
.empty .big--amber {background:linear-gradient(135deg,#FFC24B,#E8890C);box-shadow:0 6px 14px rgba(232,137,12,.28)}
.empty .big--violet{background:linear-gradient(135deg,#A78BFA,#6D4ACF);box-shadow:0 6px 14px rgba(109,74,207,.28)}
.empty .big--pink  {background:linear-gradient(135deg,#FF8FB1,#E84393);box-shadow:0 6px 14px rgba(232,67,147,.28)}
.empty .big--slate {background:linear-gradient(135deg,#94A3B8,#475569);box-shadow:0 6px 14px rgba(71,85,105,.25)}
.empty--error .big{background:linear-gradient(135deg,#F87171,#C0392B);box-shadow:0 6px 14px rgba(192,57,43,.28)}
.empty--error .big .ic--xl{color:#fff}

/* ── hero numerals — subtle gradient ink (background-clip:text). On white: action-blue→
   green, both stops ≥3:1 (AA large, numbers are ≥18px/800). On the blue heroes: white→
   pale green; with the darkened --grad-blue light stop this stays ≥3:1 everywhere.
   The plain `color` doubles as the fallback where background-clip:text is unsupported. ── */
.grad-num{color:var(--action);background:linear-gradient(115deg,var(--action) 30%,#4E9A2A);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.grad-num--onblue{color:#fff;background:linear-gradient(115deg,#FFFFFF 35%,#E4F8D2);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}

/* ═══════════ 2026 BIGGER + VIVID PASS 2 — "Home, Schedule and this menu, a little bigger"
   (owner feedback). Pure overrides layered on the vivid pass above; geometry grows,
   handlers/i18n/DOM contracts untouched. Animated bits stay transforms/opacity only. ═══════════ */

/* ── 1 · BOTTOM NAV — bigger bar (76px via --tabbar-h token above), bigger icons/labels ── */
.tab .ic{width:28px;height:28px}
.tab-label{font-size:12.5px;font-weight:800}
/* active chip scales up with the bar: 47×31 → 54×36, glow kept (per-tab gradients above) */
.tab::before{top:10px;width:54px;height:36px;border-radius:18px}
/* INACTIVE tabs: whisper of each tab's own hue (desaturated, all ≥4.5:1 on the white bar →
   label AA; icon stroke rides currentColor). :not() keeps the ID from out-ranking the
   active-state color rules. Active chip still dominates. */
#tab-home:not([aria-selected="true"])    {color:#38648C}  /* dusty brand blue   6.2:1 */
#tab-schedule:not([aria-selected="true"]){color:#625798}  /* dusty violet       6.3:1 */
#tab-clock:not([aria-selected="true"])   {color:#4E7A38}  /* dusty green        5.0:1 */
#tab-photos:not([aria-selected="true"])  {color:#8A6520}  /* dusty amber        5.3:1 */
#tab-me:not([aria-selected="true"])      {color:#3D7A74}  /* dusty teal         4.9:1 */
/* badges reposition + size up for the taller bar / wider chip */
.badge{top:7px;inset-inline-start:calc(50% + 11px);min-width:20px;height:20px;border-radius:10px;font-size:12px}
.badge--dot{min-width:11px;width:11px;height:11px;padding:0;inset-inline-start:calc(50% + 13px)}
.tab .live-dot{top:9px;inset-inline-start:calc(50% + 12px);width:10px;height:10px}

/* ── 2 · HOME — richer hero, day/date line, gradient-framed on-shift card, vivid next-shift ── */
/* greeting hero: deep blue → sky sweep. Dark stop sits under the text (inline-start) so the
   14–15px white lines stay AA; the sky lives in the far corner with the radial sheen.
   Gradient + sheen are hand-flipped for RTL (gradients ignore logical props).
   QA: #2F86D6 stop pushed 62%→100% — at 62% the 13.5–14px white line tails hit ~4.0:1 on a
   320px card (AA fail); full-box ramp keeps white ≥4.5:1 to ~70% of the axis, past the
   worst-case (long-locale date, wrapped greeting) text extent; sky corner rides the radial. */
.hello{background:linear-gradient(115deg,#1F5FA8 0%,#2F86D6 100%,#54A8E8 135%);margin:4px 0 18px}
.hello:before{background:
  radial-gradient(560px 240px at 90% -25%,rgba(91,200,245,.38),transparent 62%),
  radial-gradient(600px 240px at 88% -20%,rgba(255,255,255,.20),transparent 60%)}
html[dir=rtl] .hello{background:linear-gradient(-115deg,#1F5FA8 0%,#2F86D6 100%,#54A8E8 135%)}
html[dir=rtl] .hello:before{background:
  radial-gradient(560px 240px at 10% -25%,rgba(91,200,245,.38),transparent 62%),
  radial-gradient(600px 240px at 12% -20%,rgba(255,255,255,.20),transparent 60%)}
.hello__hi{font-size:29px}
.hello__date{position:relative;font-size:13.5px;font-weight:700;opacity:.95;margin-top:5px}
.hello__sub{margin-top:2px}
/* on-shift card: soft g-green gradient FRAME (border-box paint) + green glow */
.onshift{border:2px solid transparent;margin-bottom:17px;
  background:linear-gradient(var(--success-bg),var(--success-bg)) padding-box,
             linear-gradient(135deg,#7CC24A,#4E9A2A) border-box;
  box-shadow:0 10px 24px rgba(78,154,42,.22)}
/* timer numerals: bigger + gradient-numeral ink (dark-green pair — AA on the pale card;
   base rule's color:var(--green-d) is the no-clip fallback) */
.onshift__timer{font-size:44px;background:linear-gradient(115deg,#2F5A12,#4E9A2A);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
/* gtile-style icon plates inside the on-shift action buttons (frosted on the gradients) */
.btn__tile{width:28px;height:28px;border-radius:9px;background:rgba(255,255,255,.22);
  display:inline-grid;place-items:center;flex:none}
.btn__tile .ic{width:17px;height:17px}
/* next-shift card: bigger site name + violet countdown pill (dark ink on tint → AA) */
.next-site{font-family:var(--display);font-weight:800;font-size:19px;letter-spacing:-.01em;margin:2px 0}
.pill--violet{background:#EDE7FB;color:#5335B8}
/* section rhythm: card titles +1px, a touch more air between cards */
.card__title{font-size:19px}
.card{margin:0 0 17px}

/* ── 3 · SCHEDULE — vivid + slightly bigger ── */
/* week-hours chip → g-violet gradient pill, white text (lightest stop #7C5CD6 = 4.8:1 → AA) */
.weekchip{background:linear-gradient(135deg,#7C5CD6,#5335B8);border:none;color:#fff;
  box-shadow:0 6px 14px rgba(109,74,207,.32);border-radius:var(--r-lg)}
/* day headers bigger */
.row__lead{font-size:14px;min-width:56px}
/* TODAY: soft blue band + bold gradient-blue day label (color fallback = --action) */
.row--today{background:linear-gradient(90deg,rgba(47,134,214,.13),rgba(47,134,214,.03));border-radius:var(--r-md)}
html[dir=rtl] .row--today{background:linear-gradient(-90deg,rgba(47,134,214,.13),rgba(47,134,214,.03))}
.row--today .row__lead>div:first-child{font-size:15px;color:var(--action);
  background:linear-gradient(115deg,#2F86D6,#1F5FA8);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
/* shift rows: the color dot is now a 4px rounded BAR spanning the full row height */
.shiftrow{display:flex;gap:10px;align-items:stretch}
.shiftbar{width:4px;border-radius:2px;flex:none;align-self:stretch;min-height:40px}
.shiftrow__body{flex:1;min-width:0}
.shiftrow__body>div:first-child b{font-size:17px}   /* time + site +1px */
/* status chips: slightly bigger; ask=amber+icon, done=slate (ok/wait keep their tints) */
.st{font-size:13px;padding:6px 11px}
.st--ask::before{content:"?"}
.st--done{background:var(--surface-sunk);color:var(--ink-2)}
/* open shifts: soft gold tint card per row ("Take this shift" is already the g-green .btn--go) */
.row--open{background:linear-gradient(120deg,#FFF8E8,#FCF0D2);border:1px solid #EFDCA6;
  border-radius:var(--r-md);padding:12px;margin-top:8px}
.row--open+.row--open{border-top:1px solid #EFDCA6}
html[dir=rtl] .row--open{background:linear-gradient(-120deg,#FFF8E8,#FCF0D2)}
/* This week / Next week segmented control: bigger, active side gradient-blue + white
   (lightest stop #2B72B8 = 5.0:1 → AA at 15px/800) */
.seg button{min-height:52px;font-size:15px}
.seg button.on{background:linear-gradient(135deg,#2B72B8,#1F5FA8);color:#fff;
  box-shadow:0 4px 10px rgba(47,134,214,.35)}
/* "Days I can't work" + ICS link: bigger tap targets */
#sched-body .btn--ghost{min-height:60px;font-size:17px}
.ics-link{display:inline-block;padding:14px 18px;color:var(--action);font-weight:700;
  font-size:14px;border-radius:var(--r-sm)}

/* ═══════════ WORKER PROFILE — "My profile" sheet + the avatar everywhere ═══════════
   Avatar precedence handled in JS (app-set → Connecteam → initial circle); these are
   just the frames. Logical properties keep every placement RTL-safe. */
/* home greeting: small tasteful avatar in the hello corner (room reserved for long names) */
.hello{padding-inline-end:78px}
.hello-ava{position:absolute;inset-inline-end:16px;top:18px;width:46px;height:46px;border-radius:50%;
  border:2px solid rgba(255,255,255,.85);background:rgba(255,255,255,.22);color:#fff;
  font-family:var(--display);font-weight:800;font-size:19px;display:grid;place-items:center;
  overflow:hidden;cursor:pointer;padding:0;z-index:1;box-shadow:0 4px 12px rgba(0,0,0,.18)}
.hello-ava img{width:100%;height:100%;object-fit:cover;display:block}
/* Me hero: initial fallback inside the existing 60px circle */
.hero__avatar--init{display:grid;place-items:center;color:#fff;font-family:var(--display);font-weight:800;font-size:24px}
/* Me menu: the "My profile" row's live avatar tile */
.menu-ava{width:34px;height:34px;flex:none;border-radius:50%;overflow:hidden;display:grid;place-items:center;
  background:linear-gradient(135deg,#5BC8F5,#2F86D6);color:#fff;font-weight:800;font-size:15px;
  box-shadow:0 4px 10px rgba(47,134,214,.32)}
.menu-ava img{width:100%;height:100%;object-fit:cover;display:block}
/* profile sheet: big avatar + change/remove */
.prof-ava-wrap{text-align:center;margin:14px 0 4px}
.prof-ava{width:104px;height:104px;border-radius:50%;margin:0 auto;overflow:hidden;display:grid;place-items:center;
  background:linear-gradient(135deg,#5BC8F5,#2F86D6);border:3px solid #fff;box-shadow:0 8px 20px rgba(47,134,214,.35)}
.prof-ava img{width:100%;height:100%;object-fit:cover;display:block}
.prof-ava__init{color:#fff;font-family:var(--display);font-weight:800;font-size:44px}
/* bonus & score: three vivid stat tiles (rank / trend / photos) */
.prof-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:8px}
.prof-stat{display:flex;flex-direction:column;align-items:center;gap:4px;background:var(--surface-sunk);
  border-radius:var(--r-md);padding:10px 6px;text-align:center}
.prof-stat b{font-size:14px;font-variant-numeric:tabular-nums}
.prof-stat > span:last-child{font-size:11.5px;font-weight:700;color:var(--ink-2)}
.prof-trend{font-size:12px;font-weight:800}
/* the two bonus rules, in plain words (7.75 quality bar · 6.0 eligibility floor) */
.prof-rules{margin-top:10px;display:flex;flex-direction:column;gap:8px}
.prof-rule{display:flex;align-items:center;gap:10px;font-size:13.5px;font-weight:600;color:var(--ink-2)}
.prof-rule .gtile{width:26px;height:26px;border-radius:8px;flex:none}
.prof-rule .gtile .ic{width:15px;height:15px}

/* ═══════════ WEEKLY RECAP STORY — full-screen, per-slide vivid hue ═══════════
   All motion here is transform/opacity only; the global prefers-reduced-motion
   rule collapses it (and the JS skips auto-advance under reduced motion). */
.recap{position:fixed;inset:0;z-index:72;opacity:0;transform:translateY(14px);
  transition:opacity var(--t-base) var(--e-out),transform var(--t-base) var(--e-out);
  touch-action:pan-y;overscroll-behavior:contain}
.recap.open{opacity:1;transform:none}
.rc-slide{position:absolute;inset:0;display:grid;place-items:center;
  padding:calc(env(safe-area-inset-top,0px) + 64px) 28px calc(40px + var(--safe-b));
  color:#fff;text-align:center}
/* per-slide hue — dark second stops keep ALL white text ≥7:1 (AA everywhere) */
.rc-hue-0{background:linear-gradient(160deg,#6D4ACF,#33246E)}
.rc-hue-1{background:linear-gradient(160deg,#2F86D6,#153A66)}
.rc-hue-2{background:linear-gradient(160deg,#0E9488,#083E39)}
.rc-hue-3{background:linear-gradient(160deg,#4E9A2A,#1E4210)}
.rc-body{max-width:420px}
.rc-kicker{font-size:13px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;opacity:.88;margin-bottom:10px}
.rc-title{font-family:var(--display);font-weight:800;font-size:30px;letter-spacing:-.02em;line-height:1.1;margin:0 0 16px}
.rc-big{font-family:var(--display);font-weight:800;font-size:64px;line-height:1;margin-top:8px}
.rc-big--2{font-size:42px;margin-top:24px}
.rc-denom{font-size:.45em;opacity:.82}
.rc-num{background:linear-gradient(115deg,#FFFFFF 35%,#E4F8D2);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:#fff}
.rc-lbl{font-size:15px;font-weight:700;opacity:.94;margin-top:6px}
.rc-medal{display:inline-flex;align-items:center;gap:8px;background:rgba(255,255,255,.16);
  border:1px solid rgba(255,255,255,.34);border-radius:var(--r-pill);
  padding:9px 16px;font-weight:800;font-size:15px;margin-top:16px;margin-inline:4px}
.rc-empty{font-size:16px;font-weight:700;opacity:.94;margin-top:10px}
.rc-emoji{font-size:64px;line-height:1;margin-bottom:14px}
.rc-done{margin-top:26px;position:relative;z-index:3;width:auto;padding:0 34px;margin-inline:auto}
/* progress bars — fill is transform-only (scaleX); origin mirrors in RTL */
.rc-bars{position:absolute;top:calc(env(safe-area-inset-top,0px) + 12px);inset-inline:14px;display:flex;gap:6px;z-index:3;pointer-events:none}
.rc-bar{flex:1;height:4px;border-radius:2px;background:rgba(255,255,255,.28);overflow:hidden}
.rc-bar i{display:block;height:100%;border-radius:2px;background:#fff;transform:scaleX(0);transform-origin:left}
html[dir=rtl] .rc-bar i{transform-origin:right}
.rc-bar i.done{transform:scaleX(1)}
.rc-bar i.run{animation:rcBar 6s linear forwards}
@keyframes rcBar{from{transform:scaleX(0)}to{transform:scaleX(1)}}
/* close (X) — 48px tap target */
.rc-x{position:absolute;top:calc(env(safe-area-inset-top,0px) + 26px);inset-inline-end:12px;
  width:48px;height:48px;border:none;border-radius:50%;background:rgba(255,255,255,.16);
  color:#fff;display:grid;place-items:center;cursor:pointer;z-index:4}
/* invisible tap zones: inline-start third = back, inline-end two-thirds = next (RTL-safe) */
.rc-tap{position:absolute;top:96px;bottom:0;border:none;background:none;padding:0;cursor:pointer;z-index:2}
.rc-tap--back{inset-inline-start:0;width:34%}
.rc-tap--next{inset-inline-end:0;width:66%}
/* slide entrance (shared with the tour cards) */
.rc-in{animation:rcIn .38s var(--e-out)}
@keyframes rcIn{from{opacity:0;transform:translateY(14px) scale(.98)}to{opacity:1;transform:none}}

/* ═══════════ WELCOME TOUR — 3-card sheet ═══════════ */
.tour{text-align:center;padding:10px 6px 4px}
.tour-art{width:84px;height:84px;border-radius:26px;margin:8px auto 16px;display:grid;place-items:center;color:#fff}
.tour-art .ic--xl{width:42px;height:42px}
.tour-h{font-family:var(--display);font-weight:800;font-size:22px;letter-spacing:-.01em;margin:0 0 6px}
.tour-p{color:var(--ink-2);font-size:15px;line-height:1.5;margin:0 0 14px}
.tour-dots{display:flex;justify-content:center;gap:7px;margin-bottom:16px}
.tour-dots i{width:8px;height:8px;border-radius:50%;background:var(--line-strong);transition:transform var(--t-fast) var(--e-soft)}
.tour-dots i.on{background:var(--action);transform:scale(1.3)}

/* ═══════════ SETTINGS CONTROLS — Sounds switch + Appearance mini-seg ═══════════ */
/* switch: knob is transform-only; ::before extends the hit area to ~52px */
.swt{margin-inline-start:auto;width:54px;height:32px;border-radius:16px;border:none;padding:0;
  cursor:pointer;position:relative;flex:none;background:var(--line-strong);
  transition:background var(--t-base) var(--e-std)}
.swt::before{content:"";position:absolute;inset:-11px}
.swt::after{content:"";position:absolute;top:3px;inset-inline-start:3px;width:26px;height:26px;
  border-radius:50%;background:#fff;box-shadow:var(--e-1);
  transition:transform var(--t-base) var(--e-soft)}
.swt.on{background:var(--success)}
.swt.on::after{transform:translateX(22px)}
html[dir=rtl] .swt.on::after{transform:translateX(-22px)}
/* mini segmented control (Auto / Light / Dark) */
.mini-seg{margin-inline-start:auto;display:flex;gap:4px;background:var(--surface-sunk);border-radius:12px;padding:3px}
.mini-seg button{border:none;background:none;min-height:44px;padding:0 12px;border-radius:9px;
  font-family:var(--sans);font-size:13px;font-weight:800;color:var(--ink-2);cursor:pointer}
.mini-seg button.on{background:var(--surface);color:var(--action);box-shadow:var(--e-1)}
/* the two hues the Me rows didn't have yet (Weekly recap · App tour) */
.ic--tint-violet{background:linear-gradient(135deg,#A78BFA,#6D4ACF);color:#fff;box-shadow:0 4px 10px rgba(109,74,207,.32)}
.ic--tint-pink{background:linear-gradient(135deg,#FF8FB1,#E84393);color:#fff;box-shadow:0 4px 10px rgba(232,67,147,.32)}

/* ═══════════ DARK MODE — premium navy (never pure black) ═══════════
   JS resolves sp_theme (Auto/Light/Dark) + the OS scheme to html[data-theme=dark]
   (head bootstrap pre-paint, applyTheme() live) so ONE selector themes everything.
   Brand gradients stay vivid; text tokens re-checked for AA on the navy surfaces. */
html[data-theme=dark]{
  color-scheme:dark;
  --app-bg:#0F1B2D; --bg:#0F1B2D; --surface:#16243A; --surface-2:#182842; --surface-sunk:#0C1626;
  --overlay:rgba(2,8,18,.68);
  --ink:#E8F0FA; --ink-2:#9FB3CC; --ink-3:#7C92AD; --muted:#9FB3CC;
  --line:rgba(255,255,255,.08); --line2:rgba(255,255,255,.05); --line-strong:rgba(255,255,255,.17);
  --action:#7EB8EE; --focus:#7EB8EE; --info-ink:#8FC5F2; --warn-ink:#F5C97B;
  --success-bg:#172A10; --warn-bg:#2E2410; --danger-bg:#331714; --info-bg:#12283F;
  --danger:#F08575;
  --grade-gold:#F2C14E; --grade-pass:#8FD05E; --grade-mid:#F0A45B; --grade-low:#F08575;
  --e-1:0 1px 2px rgba(0,0,0,.35),0 1px 3px rgba(0,0,0,.3);
  --e-2:0 4px 12px rgba(0,0,0,.4),0 2px 4px rgba(0,0,0,.3);
  --e-3:0 12px 28px rgba(0,0,0,.5),0 4px 8px rgba(0,0,0,.35);
  --e-nav:0 -2px 16px rgba(0,0,0,.45);
}
/* chrome: blurred bars pick up the navy */
html[data-theme=dark] .topbar{background:rgba(15,27,45,.88)}
html[data-theme=dark] .tabbar{background:rgba(18,30,48,.96);border-top-color:var(--line)}
html[data-theme=dark] .topbtn__badge{border-color:#121E30}
/* inactive tab hues: lightened dusty versions — all ≥4.5:1 on the dark bar */
html[data-theme=dark] #tab-home:not([aria-selected="true"])    {color:#9CC3E8}
html[data-theme=dark] #tab-schedule:not([aria-selected="true"]){color:#B9ABEF}
html[data-theme=dark] #tab-clock:not([aria-selected="true"])   {color:#A5D982}
html[data-theme=dark] #tab-photos:not([aria-selected="true"])  {color:#E8C687}
html[data-theme=dark] #tab-me:not([aria-selected="true"])      {color:#8CD1C9}
/* white-surfaced controls → navy surfaces */
html[data-theme=dark] .btn--ghost{background:var(--surface);color:var(--action)}
html[data-theme=dark] .chip{background:var(--surface)}
html[data-theme=dark] .input,html[data-theme=dark] .select{background:var(--surface);color:var(--ink)}
html[data-theme=dark] .exam-opt{background:var(--surface)}
html[data-theme=dark] .exam-prog{background:var(--surface)}
html[data-theme=dark] .qt-check{background:var(--surface-sunk)}
html[data-theme=dark] .pol-card{background:var(--surface)}
html[data-theme=dark] .rsvp{background:var(--surface)}
/* skeletons shimmer in navy */
html[data-theme=dark] .skel{background:linear-gradient(100deg,#16243A 30%,#1E3150 50%,#16243A 70%);background-size:200% 100%}
/* toasts: readable panels (light --ink would invert the base rule) */
html[data-theme=dark] .toast{background:#24374F;color:#E8F0FA}
html[data-theme=dark] .toast--ok{background:#3E7A20;color:#fff}
html[data-theme=dark] .toast--bad{background:#A33529;color:#fff}
/* green-family inks that were hard-coded dark greens on pale tints */
html[data-theme=dark] .st--ok,
html[data-theme=dark] .pill--go,
html[data-theme=dark] .chip--done,
html[data-theme=dark] .qt-alldone{color:#A8DD7E}
html[data-theme=dark] .chip--done{border-color:rgba(124,194,74,.35)}
html[data-theme=dark] .qt-alldone{border-color:rgba(124,194,74,.3)}
html[data-theme=dark] .onshift__t{color:#C6EBA4}
html[data-theme=dark] .onshift__timer{color:#A8DD7E;
  background:linear-gradient(115deg,#C6EBA4,#8FD05E);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
html[data-theme=dark] .rewards-bal__ic{background:var(--success-bg);color:#A8DD7E}
/* gradient numerals: light stops on dark surfaces */
html[data-theme=dark] .grad-num{color:var(--action);
  background:linear-gradient(115deg,#7EB8EE 30%,#8FD05E);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
/* gold-tint cards (open shifts / recognition moment) → deep amber */
html[data-theme=dark] .row--open,
html[data-theme=dark] .recog-home{background:linear-gradient(120deg,#2A2210,#332A12);border-color:rgba(245,166,35,.28)}
html[data-theme=dark] .row--open+.row--open{border-top-color:rgba(245,166,35,.28)}
/* confirm zone hairlines on the dark info tint */
html[data-theme=dark] .cz{border-color:rgba(91,200,245,.25)}
html[data-theme=dark] .cz-row{border-top-color:rgba(255,255,255,.08)}
html[data-theme=dark] .weekchip{border:none}
/* danger: light token is for TEXT; solid badge/button fills keep the deep red (white label AA) */
html[data-theme=dark] .badge,
html[data-theme=dark] .topbtn__badge,
html[data-theme=dark] .me-unread,
html[data-theme=dark] .btn--danger{background:#C0392B;color:#fff}
/* misc hard-coded lights */
html[data-theme=dark] .store-val{background:rgba(15,27,45,.92);color:var(--ink)}
html[data-theme=dark] .pill--violet{background:#251C4E;color:#C9B8F5}
html[data-theme=dark] .a2hs{border-color:#3E6FA8}
html[data-theme=dark] .card--green{border-color:rgba(124,194,74,.3)}
html[data-theme=dark] .offline{border-color:rgba(245,166,35,.3)}
html[data-theme=dark] .gatebar{border-color:rgba(245,166,35,.3)}
html[data-theme=dark] .swt::after{background:#DCE7F5}
/* photos dim slightly so they don't glare on navy */
html[data-theme=dark] .thumb,
html[data-theme=dark] .sheet__photo img,
html[data-theme=dark] .hero__avatar,
html[data-theme=dark] .menu-ava img,
html[data-theme=dark] .prof-ava img,
html[data-theme=dark] .hello-ava img{filter:brightness(.86)}

/* ══════ 2026-07 PASS — one-tap start · clock-out photo gate · earned points ·
   pending-review chips · site notes. Logical props only (RTL-safe); all colors
   ride the existing AA token pairs; no new keyframes (reduced-motion clean). ══════ */

/* ITEM G: one-tap "▶ Start at <site>" — bigger label on the existing green gradient */
.btn--onetap{font-size:18px;line-height:1.25}

/* ITEM C: neutral "being checked" chip — info tint (a check, not a warning) */
.st--pend{background:var(--info-bg);color:var(--info-ink)}
.st--pend::before{content:"\1F50D\FE0E"}                     /* 🔍 text-presentation, follows dir */

/* ITEM B: earned auto-points badge in the rewards "Earned" list */
.earn-pts{flex:none;font-weight:800;font-size:14px;background:var(--success-bg);color:#3B6D11;
  border-radius:var(--r-pill);padding:5px 11px;font-variant-numeric:tabular-nums;margin-inline-start:8px}
html[data-theme=dark] .earn-pts{color:#A8DD7E}

/* ITEM E: "📌 At this site:" banner on the on-shift card — surface card on the green
   tint, info-blue title (AA), 2-line clamp; X dismisses, body reopens the full sheet */
.instr{display:flex;align-items:stretch;margin-top:12px;background:var(--surface);
  border:1px solid #BFDCF5;border-radius:14px;overflow:hidden;text-align:start}
.instr__main{flex:1;min-width:0;display:flex;gap:10px;align-items:flex-start;background:none;
  border:none;padding:10px 12px;cursor:pointer;color:var(--ink);font:inherit;text-align:start}
.instr__pin{font-size:17px;line-height:1.25;flex:none}
.instr__bd{display:flex;flex-direction:column;gap:2px;min-width:0}
.instr__bd b{font-size:13px;color:var(--info-ink)}
.instr__txt{font-size:13px;line-height:1.35;color:var(--ink-2);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.instr__hide{flex:none;width:42px;min-height:var(--tap-2);background:none;border:none;
  border-inline-start:1px solid var(--line);color:var(--ink-2);cursor:pointer;
  display:grid;place-items:center}
html[data-theme=dark] .instr{border-color:rgba(91,200,245,.25)}

/* ══ ZONES — zone-guided photo flow (the hero loop) ═══════════════════════════
   Chip rail (horizontal scroll, logical props → RTL-safe) + progress ring.
   States: todo (gray) · active (blue) · passed (green + grade) · re-clean (amber).
   Colors reuse the existing AA token pairs (chip/pill palettes). All motion is
   transform/opacity/stroke only and collapses under the global reduced-motion rule. */
.zprog{margin-top:12px;text-align:start}
.zprog__head{display:flex;align-items:center;gap:10px;margin-bottom:2px}
.zprog__t{display:flex;flex-direction:column;min-width:0;line-height:1.15}
.zprog__t b{font-family:var(--display);font-weight:800;font-size:20px;font-variant-numeric:tabular-nums}
.zprog__of{font-size:14px;color:var(--ink-2);font-weight:800}
.zprog__t > span{font-size:12.5px;color:var(--ink-2);font-weight:700}
/* progress ring — starts at 12 o'clock; dashoffset animates as zones land */
.zring{width:44px;height:44px;flex:none;transform:rotate(-90deg)}
.zring__bg,.zring__fg{fill:none;stroke-width:4.5}
.zring__bg{stroke:var(--line)}
.zring__fg{stroke:var(--green-d);stroke-linecap:round;
  transition:stroke-dashoffset var(--t-slow,.5s) var(--e-out,ease-out)}
/* chip rail — one row, momentum scroll, hidden scrollbar; --wrap variant for sheets */
.zrail{display:flex;gap:8px;overflow-x:auto;padding:6px 2px 8px;margin:2px 0 0;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.zrail::-webkit-scrollbar{display:none}
.zrail--wrap{flex-wrap:wrap;overflow:visible}
.zchip{
  flex:none;display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
  min-height:var(--tap-2);padding:0 14px;border-radius:var(--r-pill);
  font-size:14px;font-weight:700;font-family:inherit;cursor:default;
  background:var(--surface-sunk);border:1.5px solid var(--line-strong);color:var(--ink-2);
  max-width:220px;overflow:hidden;text-overflow:ellipsis;
}
button.zchip{cursor:pointer;background:#fff;color:var(--ink)}
.zchip--active{background:var(--info-bg)!important;border-color:var(--blue);color:var(--action)!important;
  box-shadow:0 0 0 3px rgba(47,134,214,.14)}
.zchip--pass{background:var(--success-bg);border-color:#BCD9AD;color:#3B6D11}
.zchip--redo{background:var(--warn-bg);border-color:#E3B75E;color:var(--warn-ink)}
.zchip__ic{display:inline-flex;align-items:center;line-height:1}
.zchip__g{font-variant-numeric:tabular-nums;font-weight:800;opacity:.85}
/* on-shift cards: the whole mini rail is one tap-target into the capture flow */
.zwrap{display:block;cursor:pointer;border-radius:14px}
/* all-done moment + warm re-clean note */
.zall{text-align:center;padding:6px 0 2px}
.zall__big{font-size:44px;line-height:1.1}
.zwarm{display:inline-block;font-weight:800;color:var(--warn-ink);background:var(--warn-bg);
  border-radius:12px;padding:10px 14px;margin-top:8px}
.zarrow{font-weight:900}
[dir=rtl] .zarrow{display:inline-block;transform:scaleX(-1)}
/* missing-zones section in the clock-out sheet */
.zmiss{margin:12px 0 14px}
.zmiss__t{display:block;font-size:14px;margin-bottom:2px;color:var(--warn-ink)}
/* dark theme — mirror the chip/pill dark rules */
html[data-theme=dark] button.zchip{background:var(--surface)}
html[data-theme=dark] .zchip{background:var(--surface-sunk)}
html[data-theme=dark] .zchip--pass{background:var(--success-bg);border-color:rgba(124,194,74,.35);color:#A8DD7E}
html[data-theme=dark] .zchip--active{background:var(--info-bg)!important}
html[data-theme=dark] .zring__fg{stroke:var(--green)}

/* ══ KEY CUSTODY — the hand-over UI. The pending-IN banner is deliberately the loudest
   element in the My-keys sheet (trust moment); everything uses logical props for RTL and
   existing tokens for AA in both themes. Motion is covered by the global reduced-motion rule. ══ */
.keybanner{background:var(--info-bg);border:2px solid var(--blue);border-radius:var(--r-xl);
  padding:18px;margin-bottom:14px}
.keybanner__t{font-family:var(--display);font-weight:800;font-size:18px;color:var(--action);
  display:flex;align-items:center;gap:8px}
.keybanner__t .ic{flex:none}
.keybanner__site{font-weight:800;font-size:16px;margin:6px 0 4px}
.keybanner__note{color:var(--ink-2)}
.key-row{display:flex;align-items:center;gap:10px;padding:12px 0;border-top:1px solid var(--line);flex-wrap:wrap}
.key-row:first-of-type{border-top:none}
.key-row__main{flex:1;min-width:0}
.key-row__act{display:flex;gap:8px;flex-wrap:wrap}
.key-row__act .btn{width:auto}
/* small honest info line on the on-shift cards: who holds this site's keys */
.keyline{display:flex;align-items:center;gap:6px;font-size:13px;font-weight:700;color:var(--ink-2);margin:0 0 6px}
.keyline .ic--xs{width:15px;height:15px;flex:none}
html[data-theme=dark] .keybanner{border-color:#4AA3E8}

/* ── grading v2: numbered problem markers + problem list (see-what-to-fix) ── */
.spot--n{display:flex;align-items:center;justify-content:center;font:800 13px/1 inherit;color:#fff;
  background:rgba(185,58,46,.82);text-shadow:0 1px 2px rgba(0,0,0,.4)}
.problist{margin:10px 0 0;text-align:start}
.prob{display:flex;gap:10px;align-items:flex-start;padding:7px 0;border-top:1px solid var(--line)}
.prob:first-child{border-top:none}
.prob__n{flex:none;width:22px;height:22px;border-radius:50%;background:var(--danger);color:#fff;
  font:800 12px/22px inherit;text-align:center}
.prob__what{font-weight:700}
.prob__where{font-size:12.5px;color:var(--ink-2,#5b6b7a)}
