/* ============================================================
   Oxford Social — TEAM APP SHELL (css/app.css)
   The "app" frame around the staff portal: tokens, the window-scrolls
   frame, the sticky top bar, the fixed sidebar / icon rail + tooltip +
   foot, the phone dock restyle, the full-screen phone menu, the search
   palette, the floating action, the alerts popover, the pwa strips,
   the gate restyle, motion, focus rings and print.

   Loaded LAST but two (app-cards.css and app-home.css follow and only
   consume the --app-* tokens declared here). Every rule is scoped under
   body.team-app (gate) or body.team-app.is-authed (dashboard); nothing
   is added to :root, so clock.html (body.clock-app) is untouched.

   House rules kept here (spec §6.4): no display on anything [hidden]
   (the global [hidden]{display:none!important} must keep winning); no
   transform / filter / contain / backdrop-filter / overflow on body,
   main.staff or #dashView (#tabSheet, #appAlerts and #appFab are fixed
   inside them); !important only in the reduced-motion block; radius 0
   except the 2px count badge; nothing under 13px.

   Spec: DESIGN-STAFF-APP.md §1, §2.2–2.9, §5, §6. Built 2026-09-19.
   ============================================================ */

/* ============================================================
   0. TOKENS (spec §6.1) — on body.team-app, never :root
   ============================================================ */
body.team-app {
  /* geometry (per-breakpoint values below, spec §1.1) */
  --app-top: 64px;
  --app-side: 0px;
  --app-dock-h: 64px;
  --app-fab-h: 56px;
  --app-pad: 16px;
  --app-gap: 16px;
  --app-card-pad: 24px 20px;
  --app-safe-t: env(safe-area-inset-top, 0px);
  --app-safe-b: env(safe-area-inset-bottom, 0px);
  /* layers */
  --app-z-top: 60;
  --app-z-side: 70;
  --app-z-fab: 74;
  --app-z-pop: 90;
  /* colour helpers — derived from the v5 tokens, no new hues */
  --app-tint: rgba(232, 163, 61, 0.08);
  --app-tint-2: rgba(232, 163, 61, 0.16);
  --app-wash: rgba(245, 241, 232, 0.04);
  --app-scrim: rgba(0, 0, 0, 0.72);
  --app-ok-line: rgba(125, 167, 123, 0.5);
  --app-bad-line: rgba(201, 107, 90, 0.5);
  --app-bad-tint: rgba(201, 107, 90, 0.08);
  --app-ink-line: rgba(245, 241, 232, 0.34);
  /* aliases the feature stylesheets reference but nobody defined */
  --line: var(--line-c);
  --line-2: var(--line-2-c);
  --ink: var(--ink-c);
  --muted: var(--muted-c);
  --bg: var(--bg-c);
  --bg-alt: var(--bg-alt-c);
  --surface: var(--panel-c);
  --error-c: var(--bad);
  /* type scale (font shorthands; tracking and case applied at the use site) */
  --app-t-eyebrow: 700 13px/1.3 var(--font-body);   /* + .28em, uppercase, amber */
  --app-t-title: 400 30px/0.96 var(--font-display); /* page title; 26 tablet; 20 phone */
  --app-t-card: 400 20px/1 var(--font-display);     /* card titles, uppercase */
  --app-t-kpi: 400 44px/1 var(--font-display);      /* big figures; 36 phone */
  --app-t-figure: 400 28px/1 var(--font-display);   /* .stat__value, in-bar totals */
  --app-t-nav: 400 15px/1 var(--font-display);      /* + .06em uppercase */
  --app-t-btn: 400 17px/1.1 var(--font-display);    /* + .08em uppercase (= .btn) */
  --app-t-body: 400 15px/1.5 var(--font-body);
  --app-t-small: 400 13px/1.4 var(--font-body);     /* the floor */
  --app-t-label: 700 13px/1.3 var(--font-body);     /* + .2em uppercase */
  /* motion */
  --app-dur-1: 120ms;
  --app-dur-2: 200ms;
  --app-dur-3: 320ms;
  --app-ease: cubic-bezier(0.2, 0.7, 0.2, 1);
}
@media (min-width: 761px) {
  body.team-app { --app-side: 72px; --app-dock-h: 0px; --app-pad: 20px; }
}
@media (min-width: 1200px) {
  body.team-app { --app-side: 248px; --app-top: 72px; --app-pad: 28px; --app-card-pad: 28px 24px; --app-fab-h: 0px; }
  body.team-app[data-side="narrow"] { --app-side: 72px; }
}
@media (max-width: 1199px) {
  body.team-app { --app-t-title: 400 26px/0.96 var(--font-display); }
}
@media (max-width: 760px) {
  body.team-app { --app-t-title: 400 20px/1 var(--font-display); --app-t-kpi: 400 36px/1 var(--font-display); }
}

/* ============================================================
   1. THE FRAME (spec §1.3) — the window scrolls at every width
   ============================================================ */
/* Anchors and programmatic scrolls land under the sticky bar. --app-top lives
   on body, so html carries the two literal sums (64+12 / 72+12). */
html:has(> body.team-app.is-authed) { scroll-padding-top: 76px; }
@media (min-width: 1200px) {
  html:has(> body.team-app.is-authed) { scroll-padding-top: 84px; }
}

/* Signed in: main is the full-bleed canvas beside the fixed rail. Overrides
   staff.css .staff and pwa.css .team-app .staff at every width. */
body.team-app.is-authed main.staff {
  max-width: none;
  margin: 0;
  padding: 0 0 0 var(--app-side);
  min-height: 100svh;
  transition: padding-left var(--app-dur-2) var(--app-ease);
}
body.team-app.is-authed #dashView {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
body.team-app.is-authed #dashView > * { min-width: 0; }
body.team-app.is-authed #dashHead { order: -3; }
body.team-app.is-authed #attendanceStatus { order: -2; }
body.team-app.is-authed #onboardBanner { order: -1; }

/* Content children share one column: 16 / 20 / 28px gutters, 1600px cap. */
body.team-app.is-authed :is(.panel, #onboardBanner, #attendanceStatus) {
  width: 100%;
  max-width: calc(1600px + 2 * var(--app-pad));
  margin-inline: auto;
  padding-inline: var(--app-pad);
}
body.team-app.is-authed .panel {
  padding-top: var(--app-gap);
  padding-bottom: calc(var(--app-dock-h) + var(--app-safe-b) + var(--app-fab-h) + 24px);
  scroll-margin-top: calc(var(--app-top) + 12px);
}
@media (min-width: 1200px) {
  body.team-app.is-authed .panel { padding-bottom: 64px; }
}
/* attendance.js's status aside becomes a full-width strip under the bar. */
body.team-app.is-authed #attendanceStatus {
  margin-block: 0;
  border-radius: 0;
  border-left: 0;
  border-right: 0;
  font-size: 14px;
}
/* In-panel stickies that assumed the window starts at 0. */
body.team-app.is-authed .wf-nav,
body.team-app.is-authed .schedule-library { top: calc(var(--app-top) + 16px); }

/* The toast clears the dock and the floating action. */
body.team-app.is-authed .toast {
  bottom: calc(var(--app-dock-h) + var(--app-safe-b) + var(--app-fab-h) + 24px);
}

/* ============================================================
   1.4 THE TOP BAR — header.shell#dashHead (sticky, z 60)
   ============================================================ */
body.team-app.is-authed #dashHead {
  position: sticky;
  top: 0;
  z-index: var(--app-z-top);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  min-height: calc(var(--app-top) + var(--app-safe-t));
  margin: 0;
  padding: var(--app-safe-t) var(--app-pad) 0;
  background: var(--bg-c);
  border: 0;
  border-bottom: 1px solid var(--line-c);
}
body.team-app.is-authed #dashHead .shell__left {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  flex-wrap: nowrap;
  gap: 4px;
  min-width: 0;
}
body.team-app.is-authed #dashHead .shell__brand,
body.team-app.is-authed #dashHead .shell__sep { display: none; }
body.team-app.is-authed #dashHead .shell__eyebrow {
  display: block;
  max-width: 100%;
  margin: 0;
  font: var(--app-t-eyebrow);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--accent-c);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
body.team-app.is-authed #dashHead #dashTitle {
  max-width: 100%;
  margin: 0;
  font: var(--app-t-title);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink-c);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  outline: none;
}
body.team-app.is-authed #dashHead .shell__right {
  display: flex;
  align-items: center;
  justify-self: end;
  flex-wrap: nowrap;
  gap: 10px;
  min-width: 0;
}
body.team-app.is-authed #dashHead .shell__ico { width: 22px; height: 22px; flex: none; }

/* Search or go to… */
body.team-app.is-authed #appSearch {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 260px;
  height: 44px;
  padding: 0 12px;
  background: var(--bg-alt-c);
  border: 1px solid var(--line-2-c);
  border-radius: 0;
  color: var(--muted-c);
  font: var(--app-t-small);
  text-align: left;
  cursor: pointer;
  transition: border-color var(--app-dur-1) var(--app-ease), color var(--app-dur-1) var(--app-ease);
}
body.team-app.is-authed #appSearch:hover { border-color: var(--ink-c); color: var(--text-c); }
body.team-app.is-authed #appSearch .shell__search-text {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
body.team-app.is-authed #appSearch .shell__kbd {
  flex: none;
  padding: 4px 6px;
  border: 1px solid var(--line-2-c);
  color: var(--text-c);
  font: 500 13px/1 var(--font-body);
  white-space: nowrap;
}

/* The bell and its count. */
body.team-app.is-authed #appAlertsBtn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--line-2-c);
  border-radius: 0;
  color: var(--text-c);
  cursor: pointer;
  transition: border-color var(--app-dur-1) var(--app-ease), color var(--app-dur-1) var(--app-ease);
}
body.team-app.is-authed #appAlertsBtn:hover,
body.team-app.is-authed #appAlertsBtn[aria-expanded="true"] { border-color: var(--ink-c); color: var(--ink-c); }
body.team-app.is-authed #appAlertsCount {
  position: absolute;
  top: 4px;
  right: 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 4px;
  background: var(--accent-c);
  color: var(--on-accent-c);
  font: 700 13px/1 var(--font-body);
  font-variant-numeric: tabular-nums;
  animation: app-pop var(--app-dur-1) var(--app-ease);
}

/* The clock, who, the role badge, Lock. */
body.team-app.is-authed #appClock {
  padding: 0 4px;
  font: 400 22px/1 var(--font-display);
  letter-spacing: 0.02em;
  color: var(--ink-c);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
body.team-app.is-authed #dashWho {
  font-size: 15px;
  color: var(--text-c);
  white-space: nowrap;
}
body.team-app.is-authed #dashRole {
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 10px;
  border: 1px solid var(--line-2-c);
  color: var(--text-c);
  font: 700 13px/1 var(--font-body);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
}
body.team-app.is-authed #dashRole.shell__badge--admin { background: var(--accent-c); border-color: var(--accent-c); color: var(--on-accent-c); }
body.team-app.is-authed #dashRole.shell__badge--manager { border-color: var(--ink-c); color: var(--ink-c); }
body.team-app.is-authed #logoutBtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 14px;
  background: transparent;
  border: 2px solid var(--ink-c);
  border-radius: 0;
  color: var(--ink-c);
  font: 400 15px/1 var(--font-display);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color var(--app-dur-1) var(--app-ease), border-color var(--app-dur-1) var(--app-ease);
}
body.team-app.is-authed #logoutBtn:hover { border-color: var(--accent-c); color: var(--accent-c); }
body.team-app.is-authed #logoutBtn svg { flex: none; }

/* Tablet: icon-only search, no name. */
@media (max-width: 1199px) {
  body.team-app.is-authed #appSearch { min-width: 0; width: 44px; padding: 0; justify-content: center; }
  body.team-app.is-authed #appSearch .shell__search-text,
  body.team-app.is-authed #appSearch .shell__kbd { display: none; }
  body.team-app.is-authed #dashWho { display: none; }
}
/* Phone: 64px bar, date only, bell + badge + icon-only Lock. */
@media (max-width: 760px) {
  body.team-app.is-authed #dashHead { gap: 8px; }
  body.team-app.is-authed #dashHead .shell__right { gap: 8px; }
  body.team-app.is-authed #appEyebrow,
  body.team-app.is-authed .shell__eyebrow-sep,
  body.team-app.is-authed #appSearch,
  body.team-app.is-authed #appClock { display: none; }
  body.team-app.is-authed #dashRole { height: 26px; padding: 0 8px; }
  body.team-app.is-authed #logoutBtn { width: 44px; padding: 0; gap: 0; }
  body.team-app.is-authed #logoutBtn .shell__lock-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
}

/* ============================================================
   2.2 THE SIDEBAR — div.rail#tabRail (fixed at ≥761; pwa.css hides it ≤760)
   ============================================================ */
@media (min-width: 761px) {
  body.team-app.is-authed #tabRail {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    z-index: var(--app-z-side);
    display: flex;
    flex-direction: column;
    align-items: stretch;
    width: var(--app-side);
    margin: 0;
    padding: 0 0 var(--app-safe-b);
    background: var(--bg-alt-c);
    border: 0;
    border-right: 1px solid var(--line-c);
    /* The rail is its own size container: the narrow (icon-only) recipe
       below keys off its real width, so the tablet rail and the collapsed
       desktop sidebar share one block. Layout containment clips nothing
       (#appTip still paints outside) and nothing fixed lives inside. */
    container: rail / inline-size;
    transition: width var(--app-dur-2) var(--app-ease);
  }
  /* The horizontal-rail arrows can never be needed on a column. */
  body.team-app.is-authed #tabRail .rail__arrow { display: none; }
}
/* Menu is the phone dock's target only; never a visible control here. */
body.team-app #railMenu { display: none; }

/* Brand row — the height of the top bar, so the two hairlines meet. */
body.team-app .rail__brand {
  flex: none;
  display: flex;
  align-items: center;
  height: calc(var(--app-top) + var(--app-safe-t));
  padding: var(--app-safe-t) 16px 0;
  border-bottom: 1px solid var(--line-c);
}
body.team-app .rail__brand-link {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  min-height: 44px;
  color: var(--ink-c);
  text-decoration: none;
}
body.team-app .rail__brand-link:hover { color: var(--ink-c); }
body.team-app .rail__mark { flex: none; width: 32px; height: 32px; color: var(--accent-c); }
body.team-app .rail__brand-text { display: flex; flex-direction: column; min-width: 0; }
body.team-app .rail__brand-text strong {
  font: 400 18px/1 var(--font-display);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink-c);
  white-space: nowrap;
}
body.team-app .rail__brand-text small {
  margin-top: 3px;
  font: 400 13px/1.2 var(--font-body);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted-c);
  white-space: nowrap;
}

/* The vertical scroller. When the list is taller than the screen (a short
   laptop viewport, or the collapsed rail) the thin scrollbar is the cue that
   more sits below, together with the foot's top hairline: no gradient, no
   fade. No scrollbar-gutter:stable — on classic-scrollbar platforms it would
   leave a permanent empty strip at the right edge that the hover and active
   washes could not reach whenever the list does fit. */
body.team-app.is-authed #railScroll {
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  overflow: hidden auto;
  scrollbar-width: thin;
  scrollbar-color: var(--line-2-c) transparent;
}
body.team-app .rail__tabs {
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
  align-items: stretch;
  gap: 0;
  margin: 0;
  padding: 6px 0 12px;
  overflow: visible;
}
/* One item. .tab[hidden] keeps display:none via the global !important rules. */
body.team-app .rail__tabs .tab {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  flex: none;
  width: 100%;
  min-height: 44px;
  padding: 0 16px 0 13px;
  border: 0;
  border-left: 3px solid transparent;
  border-radius: 0;
  background: transparent;
  color: var(--text-c);
  font: var(--app-t-nav);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--app-dur-1) var(--app-ease), color var(--app-dur-1) var(--app-ease);
}
body.team-app .rail__tabs .tab__icon { width: 22px; height: 22px; flex: 0 0 22px; }
body.team-app .rail__tabs .tab__label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* The one 2px radius in the app: the count badge. */
body.team-app .rail__tabs .tab__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  min-width: 22px;
  height: 22px;
  margin: 0 0 0 auto;
  padding: 0 6px;
  border: 0;
  border-radius: 2px;
  background: var(--accent-c);
  color: var(--on-accent-c);
  font: 700 13px/1 var(--font-body);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
body.team-app .rail__tabs .tab__lock { width: 11px; height: 13px; flex: none; background: currentColor; opacity: 1; }
body.team-app .rail__tabs .tab:hover { background: var(--app-wash); color: var(--ink-c); border-left-color: transparent; }
body.team-app .rail__tabs .tab:active { background: var(--app-tint-2); }
/* Active = amber text + amber icon + 3px amber bar + 8% amber wash + aria-selected. */
body.team-app .rail__tabs .tab.is-active,
body.team-app .rail__tabs .tab[aria-selected="true"] {
  background: var(--app-tint);
  color: var(--accent-c);
  border-left-color: var(--accent-c);
}
body.team-app .rail__tabs .tab:focus-visible { outline: 2px solid var(--accent-c); outline-offset: -2px; }

/* Group headings — the existing separators, no wrappers: MINE · VENUE · MONEY.
   .rail__sep[hidden] keeps winning (staff.css) when a group is absent. */
body.team-app .rail__sep {
  display: block;
  flex: none;
  width: auto;
  height: auto;
  margin: 12px 0 4px;
  padding: 0 16px;
  background: transparent;
  font: var(--app-t-label);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--muted-c);
  white-space: nowrap;
  overflow: hidden;
}
body.team-app .rail__sep::before { content: attr(data-group); }
body.team-app .rail__sep[data-group="mine"] { margin-top: 6px; }

/* The tooltip for the narrow rail: a sibling of #railScroll, so its
   overflow cannot clip it; js/app-shell.js sets top and text. */
body.team-app #appTip {
  position: absolute;
  left: calc(100% + 10px);
  top: 0;
  z-index: 1;
  height: 36px;
  padding: 0 12px;
  background: var(--ink-c);
  color: var(--bg-c);
  font: 700 13px/36px var(--font-body);
  white-space: nowrap;
  pointer-events: none;
  border-radius: 0;
}

/* The foot: Install app (proxied), Visit website, Collapse — one row of three
   44px icon buttons, so the owner's sixteen items fit a 1080p screen without
   the rail scrolling. Labels stay in the DOM (clipped) and #appTip names each
   on hover and focus (js/app-shell.js). */
body.team-app #appSideFoot {
  flex: none;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-evenly;
  gap: 4px;
  margin-top: auto;
  padding: 6px 8px;
  border-top: 1px solid var(--line-c);
}
body.team-app .rail__foot-item {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  flex: none;
  width: 44px;
  min-height: 44px;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  color: var(--text-c);
  font: 500 14px/1.2 var(--font-body);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--app-dur-1) var(--app-ease), color var(--app-dur-1) var(--app-ease);
}
body.team-app .rail__foot-item:hover { background: var(--app-wash); color: var(--ink-c); }
body.team-app .rail__foot-ico { flex: none; width: 20px; height: 20px; }
body.team-app .rail__foot-ico--expand { display: none; }
body.team-app .rail__foot-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* The collapse toggle is a desktop control only (the tablet rail is always narrow). */
@media (max-width: 1199px) {
  body.team-app #appSideToggle { display: none; }
}

/* ============================================================
   2.3 THE NARROW RAIL — 72px: the tablet range, and desktop when
   body[data-side="narrow"]. Keyed off the rail's own width.
   ============================================================ */
@container rail (max-width: 120px) {
  body.team-app .rail__brand { padding-left: 0; padding-right: 0; justify-content: center; }
  body.team-app .rail__brand-link { justify-content: center; width: 44px; gap: 0; }
  body.team-app .rail__brand-text,
  body.team-app .rail__tabs .tab__label,
  body.team-app .rail__foot-label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  body.team-app .rail__tabs .tab {
    justify-content: center;
    gap: 0;
    width: 100%;
    min-height: 52px;
    padding: 0;
    border-left-width: 3px;
  }
  /* A 13px digit in a 20px square at the icon's top-right. */
  body.team-app .rail__tabs .tab__count {
    position: absolute;
    top: 6px;
    right: 12px;
    min-width: 20px;
    height: 20px;
    margin: 0;
    padding: 0 4px;
    font: 700 13px/20px var(--font-body);
  }
  body.team-app .rail__tabs .tab__lock {
    position: absolute;
    right: 14px;
    bottom: 8px;
    width: 9px;
    height: 11px;
  }
  /* Headings fall back to hairlines. */
  body.team-app .rail__sep {
    height: 1px;
    margin: 10px 16px;
    padding: 0;
    background: var(--line-c);
    font-size: 13px;
    line-height: 0;
  }
  body.team-app .rail__sep::before { content: none; }
  body.team-app #appSideFoot { flex-direction: column; justify-content: flex-start; padding: 8px 0; }
  body.team-app .rail__foot-item { justify-content: center; width: 44px; margin: 0 auto; padding: 0; gap: 0; }
  body.team-app .rail__foot-ico--collapse { display: none; }
  body.team-app .rail__foot-ico--expand { display: block; }
}

/* ============================================================
   2.2b THE SHORT DESKTOP — ≥1200 wide but ≤960 tall (a 1440×900 or
   1536×864 laptop, a 1080p monitor once the browser chrome is taken off).
   The owner's sixteen items and three headings do not fit beside a 72px
   brand row with 12/4 heading margins (815px of list in a 771px scroller
   at 900), so the frame drops to 64px — brand row, top bar and anchor
   offset together — and the list gives up its slack: each heading sits on
   one 13px line with 6/2 margins and the list and the foot lose a few
   pixels of padding. Every item keeps its 44px. Budget at 1440×900
   (owner): list 10 + 16×44 + headings 19+21+21 = 775 in a scroller of
   900 − brand 64 − foot 53 = 783. Under ~890px tall the list scrolls
   whatever the padding does (16 × 44 alone is 704): then the thin
   scrollbar and the foot's hairline are the cue.
   ============================================================ */
@media (min-width: 1200px) and (max-height: 960px) {
  body.team-app { --app-top: 64px; }
  html:has(> body.team-app.is-authed) { scroll-padding-top: 76px; }
  body.team-app .rail__tabs { padding: 4px 0 6px; }
  body.team-app .rail__sep { margin: 6px 0 2px; line-height: 1; }
  body.team-app .rail__sep[data-group="mine"] { margin-top: 4px; }
  body.team-app #appSideFoot { padding: 4px 8px; }
  /* Collapsed: the icon items come down to the 44px floor (from 52), the
     hairlines and the foot column tighten the same way. Three stacked foot
     rows mean the narrow rail still scrolls at 900 — by ~60px, not ~230. */
  @container rail (max-width: 120px) {
    body.team-app .rail__tabs .tab { min-height: 44px; }
    body.team-app .rail__sep { margin: 6px 16px; }
    body.team-app #appSideFoot { padding: 4px 0; }
  }
}

/* ============================================================
   2.5 THE PHONE DOCK — nav.app-dock (built by js/pwa.js; restyled here)
   ============================================================ */
@media (max-width: 760px) {
  body.team-app.is-authed .app-dock {
    grid-template-columns: repeat(5, minmax(0, 1fr));
    padding: 4px max(6px, env(safe-area-inset-right)) calc(4px + var(--app-safe-b)) max(6px, env(safe-area-inset-left));
    background: var(--panel-c);
    border-top: 1px solid var(--line-2-c);
  }
  body.team-app .app-dock button {
    min-height: 56px;
    gap: 4px;
    padding: 0 2px;
    border-top: 2px solid transparent;
    border-radius: 0;
    color: var(--text-c);
    font: 500 13px/1.2 var(--font-body);
    transition: background var(--app-dur-1) var(--app-ease), color var(--app-dur-1) var(--app-ease);
  }
  body.team-app .app-dock button span {
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  body.team-app .app-dock button svg { width: 22px; height: 22px; }
  body.team-app .app-dock button[aria-current="page"] {
    color: var(--accent-c);
    border-top-color: var(--accent-c);
    background: var(--app-tint);
  }
  body.team-app .app-dock button:focus-visible { outline: 2px solid var(--accent-c); outline-offset: -2px; }
}

/* ============================================================
   2.6 THE FULL-SCREEN MENU — div.tabsheet#tabSheet (phone)
   ============================================================ */
body.team-app .tabsheet { background: var(--app-scrim); }
/* Whole screen; max-height:none beats pwa.css's 85svh. The grid takes
   margin-top:auto so it sits at the thumb end while the head stays put —
   and, unlike justify-content:flex-end, the top still scrolls into view
   when the list is taller than the screen. */
body.team-app .tabsheet__panel {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 16px;
  width: 100%;
  height: 100dvh;
  max-height: none;
  padding: calc(var(--app-safe-t) + 16px) 16px calc(var(--app-safe-b) + 16px);
  background: var(--bg-c);
  border: 0;
  overflow-y: auto;
}
body.team-app .tabsheet:not([hidden]) .tabsheet__panel {
  animation: app-sheet-in var(--app-dur-3) var(--app-ease);
}
body.team-app .tabsheet__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 44px;
  margin: 0;
}
body.team-app #tabSheetTitle {
  margin: 0;
  font: var(--app-t-eyebrow);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--accent-c);
}
body.team-app #tabSheetClose {
  min-height: 44px;
  padding: 0 8px;
  color: var(--ink-c);
  font: 500 15px/1 var(--font-body);
  text-decoration: underline;
  text-underline-offset: 3px;
}
body.team-app #appSheetWho {
  margin: 0;
  font: 400 15px/1.4 var(--font-body);
  color: var(--text-c);
}
body.team-app #appSheetWho:empty { display: none; }
body.team-app #appSheetTools { display: flex; flex-direction: column; gap: 8px; }
body.team-app .tabsheet__tool {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 52px;
  padding: 0 12px;
  background: var(--panel-c);
  border: 1px solid var(--line-c);
  border-radius: 0;
  color: var(--text-c);
  font: 500 15px/1.2 var(--font-body);
  text-align: left;
  cursor: pointer;
}
body.team-app .tabsheet__tool:hover { color: var(--ink-c); border-color: var(--line-2-c); }
body.team-app .tabsheet__tool-ico { flex: none; width: 22px; height: 22px; }
body.team-app #tabSheetGrid {
  margin-top: auto;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  background: var(--line-c);
  border: 1px solid var(--line-c);
}
body.team-app .tabsheet__cell {
  min-height: 64px;
  padding: 0 16px;
  background: var(--panel-c);
  border: 0;
  border-left: 3px solid transparent;
  color: var(--text-c);
  font: var(--app-t-nav);
  font-size: 16px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
body.team-app .tabsheet__cell.is-active,
body.team-app .tabsheet__cell[aria-current="page"] {
  color: var(--accent-c);
  border-left-color: var(--accent-c);
  background: var(--panel-c);
}
body.team-app .tabsheet__cell:hover { color: var(--ink-c); background: var(--bg-c); }
body.team-app .tabsheet__cell.is-active:hover,
body.team-app .tabsheet__cell[aria-current="page"]:hover { color: var(--accent-c); }
body.team-app .tabsheet__cell:focus-visible { outline: 2px solid var(--accent-c); outline-offset: -2px; }
body.team-app .tabsheet__cell .tab__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  margin: 0;
  padding: 0 6px;
  border: 0;
  border-radius: 2px;
  background: var(--accent-c);
  color: var(--on-accent-c);
  font: 700 13px/1 var(--font-body);
  letter-spacing: 0;
}

/* ============================================================
   2.7 THE SEARCH PALETTE — dialog.app-palette#appPalette (native, top layer)
   ============================================================ */
body.team-app .app-palette {
  width: min(640px, calc(100vw - 32px));
  max-height: calc(100dvh - 12vh - 24px);
  margin: 12vh auto 0;
  padding: 0;
  border: 1px solid var(--line-2-c);
  border-radius: 0;
  background: var(--panel-c);
  color: var(--ink-c);
  box-shadow: none;
  overflow: auto;
}
/* Literal scrim: ::backdrop cannot read body's custom properties in every engine. */
body.team-app .app-palette::backdrop { background: rgba(0, 0, 0, 0.72); }

/* The PWA "App info" dialog js/pwa.js builds: same recipe as the other native
   dialogs (pwa.css gives it a shadow and a rounded look). */
body.team-app .app-help {
  border-radius: 0;
  background: var(--panel-c);
  border: 1px solid var(--line-2-c);
  color: var(--ink-c);
  box-shadow: none;
}
body.team-app .app-help::backdrop { background: rgba(0, 0, 0, 0.72); }
body.team-app .app-help .app-button { border-radius: 0; min-height: 44px; }
body.team-app .app-palette__form { display: flex; flex-direction: column; margin: 0; }
body.team-app .app-palette__eyebrow {
  margin: 0;
  padding: 14px 16px 10px;
  font: var(--app-t-eyebrow);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--accent-c);
}
body.team-app #appPaletteInput {
  width: 100%;
  height: 56px;
  margin: 0;
  padding: 0 16px;
  background: var(--bg-c);
  border: 0;
  border-bottom: 1px solid var(--line-2-c);
  border-radius: 0;
  color: var(--ink-c);
  font: 400 17px/1.2 var(--font-body);
  outline: none;
  transition: border-color var(--app-dur-1) var(--app-ease);
}
body.team-app #appPaletteInput:focus,
body.team-app #appPaletteInput:focus-visible { border-bottom-color: var(--accent-c); outline: none; }
body.team-app #appPaletteList {
  list-style: none;
  margin: 0;
  padding: 8px 0;
  max-height: min(60dvh, 400px);
  overflow: auto;
}
body.team-app #appPaletteList li {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 48px;
  padding: 0 16px 0 13px;
  border-left: 3px solid transparent;
  color: var(--ink-c);
  font: 400 15px/1.3 var(--font-body);
  cursor: pointer;
}
body.team-app #appPaletteList li > svg { flex: none; width: 22px; height: 22px; color: var(--text-c); }
body.team-app #appPaletteList li[aria-selected="true"] { background: var(--app-tint); border-left-color: var(--accent-c); }
body.team-app #appPaletteList li[aria-selected="true"] > svg { color: var(--accent-c); }
body.team-app #appPaletteList li:hover { background: var(--app-wash); }
/* Row anatomy: label (Anton) on the left, kicker on the right. Class names
   first; the structural fallbacks cover a bare span pair. */
body.team-app #appPaletteList .app-palette__label,
body.team-app #appPaletteList li[role="option"] > span:first-of-type {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: var(--app-t-nav);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-c);
}
body.team-app #appPaletteList .app-palette__kicker,
body.team-app #appPaletteList li[role="option"] > span:last-of-type:not(:first-of-type) {
  flex: none;
  margin-left: auto;
  font: var(--app-t-small);
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-c);
  font-variant-numeric: tabular-nums;
}
body.team-app #appPaletteList .app-palette__row--none,
body.team-app #appPaletteList li:not([role="option"]) { color: var(--text-c); cursor: default; }
body.team-app .app-palette__hint {
  margin: 0;
  padding: 10px 16px 12px;
  border-top: 1px solid var(--line-c);
  font: var(--app-t-small);
  color: var(--muted-c);
}
@media (max-width: 1199px) {
  body.team-app .app-palette { width: min(560px, calc(100vw - 32px)); }
}
@media (max-width: 760px) {
  body.team-app .app-palette {
    width: calc(100vw - 32px);
    margin-top: calc(var(--app-safe-t) + 16px);
    max-height: calc(100dvh - var(--app-safe-t) - 32px);
  }
}

/* ============================================================
   2.8 THE FLOATING ACTION — button.app-fab#appFab (≤1199; mirrors a real control)
   ============================================================ */
body.team-app.is-authed #appFab {
  position: fixed;
  right: 16px;
  bottom: calc(var(--app-dock-h) + var(--app-safe-b) + 16px);
  z-index: var(--app-z-fab);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 56px;
  padding: 0 20px 0 16px;
  background: var(--accent-c);
  border: 0;
  border-radius: 0;
  color: var(--on-accent-c);
  font: 400 15px/1 var(--font-display);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  animation: app-rise var(--app-dur-2) var(--app-ease);
  transition: background var(--app-dur-1) var(--app-ease);
}
body.team-app.is-authed #appFab:hover { background: var(--accent-hover-c); }
body.team-app.is-authed #appFab:active { transform: translateY(1px); }
body.team-app.is-authed #appFab .app-fab__ico { flex: none; width: 22px; height: 22px; }
@media (min-width: 761px) and (max-width: 1199px) {
  body.team-app.is-authed #appFab { right: 24px; bottom: 24px; }
}
@media (min-width: 1200px) {
  body.team-app.is-authed #appFab { display: none; }
}

/* ============================================================
   2.9 THE ALERTS POPOVER — div.app-alerts#appAlerts (z 90, non-modal)
   ============================================================ */
body.team-app.is-authed #appAlerts {
  position: fixed;
  top: calc(var(--app-top) + var(--app-safe-t) + 8px);
  right: var(--app-pad);
  z-index: var(--app-z-pop);
  width: 400px;
  max-width: calc(100vw - 2 * var(--app-pad));
  max-height: calc(100dvh - var(--app-top) - var(--app-safe-t) - 32px);
  padding: 16px 0 8px;
  overflow: auto;
  background: var(--panel-c);
  border: 1px solid var(--line-2-c);
  color: var(--ink-c);
}
body.team-app.is-authed #appAlertsTitle {
  margin: 0;
  padding: 0 16px 12px;
  font: var(--app-t-card);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink-c);
}
body.team-app.is-authed #appAlertsList {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--line-c);
}
body.team-app.is-authed #appAlertsList > li {
  border-bottom: 1px solid var(--line-c);
  font: 400 15px/1.3 var(--font-body);
  color: var(--ink-c);
}
/* A row without a button (offline, the empty line) still reads as a row. */
body.team-app.is-authed #appAlertsList > li:not(:has(.app-alert)) {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 48px;
  padding: 0 16px;
}
body.team-app.is-authed .app-alert {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 48px;
  padding: 0 16px;
  background: transparent;
  border: 0;
  border-radius: 0;
  color: var(--ink-c);
  font: 400 15px/1.3 var(--font-body);
  text-align: left;
  cursor: pointer;
  transition: background var(--app-dur-1) var(--app-ease);
}
body.team-app.is-authed button.app-alert:hover { background: var(--app-wash); }
/* app-shell.js renders a span.app-alert--static (offline) and a p.app-alert--empty. */
body.team-app.is-authed .app-alert--static,
body.team-app.is-authed .app-alert--empty { cursor: default; color: var(--text-c); }
body.team-app.is-authed .app-alert__ico,
body.team-app.is-authed .app-alert > svg:first-child { flex: none; width: 24px; height: 24px; color: var(--accent-c); }
body.team-app.is-authed .app-alert__text,
body.team-app.is-authed .app-alert > span:first-of-type { flex: 1 1 auto; min-width: 0; }
body.team-app.is-authed .app-alert__count,
body.team-app.is-authed .app-alert .tab__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  min-width: 22px;
  height: 22px;
  margin: 0;
  padding: 0 6px;
  border: 0;
  border-radius: 2px;
  background: var(--accent-c);
  color: var(--on-accent-c);
  font: 700 13px/1 var(--font-body);
  font-variant-numeric: tabular-nums;
}
body.team-app.is-authed .app-alert__chev,
body.team-app.is-authed .app-alert > svg:last-child:not(:first-child) { flex: none; width: 18px; height: 18px; color: var(--text-c); }
body.team-app.is-authed #appAlertsWhen {
  margin: 0;
  padding: 10px 16px 0;
  font: var(--app-t-small);
  color: var(--text-c);
}
body.team-app.is-authed #appAlertsClose {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin: 0 16px;
  padding: 0;
  background: none;
  border: 0;
  color: var(--ink-c);
  font: 500 15px/1 var(--font-body);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
@media (min-width: 761px) and (max-width: 1199px) {
  body.team-app.is-authed #appAlerts { width: 360px; }
}
@media (max-width: 760px) {
  body.team-app.is-authed #appAlerts {
    top: calc(var(--app-top) + var(--app-safe-t));
    left: 0;
    right: 0;
    width: auto;
    max-width: none;
    max-height: 60vh;
    border-left: 0;
    border-right: 0;
  }
}

/* ============================================================
   PWA STRIPS (js/pwa.js builds them; pwa.css is not edited)
   ============================================================ */
/* The appbar belongs to the gate: hidden once signed in, retokened otherwise. */
body.team-app.is-authed .appbar { display: none; }
body.team-app .appbar {
  background: var(--bg-alt-c);
  border-bottom-color: var(--line-c);
  color: var(--ink-c);
}
body.team-app .appbar__brand { color: var(--ink-c); }
body.team-app .appbar__brand strong { font: 400 18px/1.05 var(--font-display); text-transform: uppercase; }
body.team-app .appbar__brand small,
body.team-app .appbar__site { color: var(--muted-c); font-size: 13px; }
body.team-app .appbar__site:hover { color: var(--ink-c); }
body.team-app .app-button { border-color: var(--line-2-c); color: var(--ink-c); border-radius: 0; }
body.team-app .app-button:hover,
body.team-app .app-button:focus-visible { border-color: var(--accent-c); color: var(--accent-c); }
body.team-app .app-notice {
  background: var(--accent-c);
  color: var(--on-accent-c);
  font-size: 14px;
  font-weight: 500;
}
body.team-app .app-update {
  background: var(--panel-c);
  color: var(--ink-c);
  border-bottom: 1px solid var(--line-c);
  font-size: 14px;
}
@media (min-width: 761px) {
  body.team-app.is-authed .app-notice,
  body.team-app.is-authed .app-update {
    padding-left: calc(var(--app-side) + 16px);
    transition: padding-left var(--app-dur-2) var(--app-ease);
  }
}

/* ============================================================
   THE ONBOARDING STRIP — #onboardBanner, dense (the column's gutters, one row)
   ============================================================ */
body.team-app.is-authed #onboardBanner {
  align-items: center;
  gap: 12px 16px;
  margin: 0;
  padding-block: 12px;
  border: 0;
  border-bottom: 1px solid var(--line-c);
  border-radius: 0;
  background: var(--accent-c);
  color: var(--on-accent-c);
}
body.team-app.is-authed #onboardBanner svg { width: 22px; height: 22px; }
body.team-app.is-authed #onboardBanner p {
  margin: 0;
  font: 500 15px/1.4 var(--font-body);
  color: var(--on-accent-c);
}
body.team-app.is-authed #onboardGo {
  min-height: 44px;
  padding: 0 16px;
  border-radius: 0;
  font: 400 15px/1 var(--font-display);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
@media (max-width: 760px) {
  body.team-app.is-authed #onboardBanner { gap: 10px 12px; }
}

/* ============================================================
   5. THE GATE — body.team-app #gateView (no markup change; ids and
   class toggles kept; clock.html is not team-app)
   ============================================================ */
/* Signed out, main is a plain block; the gate sizes itself. */
body.team-app:not(.is-authed) main.staff {
  max-width: none;
  margin: 0;
  padding: 0;
  min-height: calc(100svh - 76px);
}
body.team-app #gateView {
  max-width: 1040px;
  margin: 16px auto 0;
  padding: 24px var(--app-pad) 48px;
  gap: 24px;
}
/* 5.2 Intro */
body.team-app #gateView .gate__intro {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  max-width: none;
  margin: 0;
  text-align: left;
}
/* staff.css's phone ordering (#gateTitle / #gateNotice order:-2) targets the
   gate's own flex column; inside the intro column it would lift the title
   above its eyebrow, so the intro reads in DOM order at every width. */
body.team-app #gateView .gate__intro > * { order: 0; }
body.team-app #gateView .gate__intro .eyebrow {
  display: inline-flex;
  margin: 0;
  font: var(--app-t-eyebrow);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--accent-c);
}
body.team-app #gateView #gateTitle {
  margin: 0;
  font: 400 clamp(32px, 5vw, 48px)/0.96 var(--font-display);
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--ink-c);
}
body.team-app #gateView .gate__intro .gate__lede {
  margin: 0;
  max-width: 60ch;
  font: var(--app-t-body);
  color: var(--text-c);
}
body.team-app #gateView #gateNotice {
  min-height: 1.3rem;
  margin: 0;
  text-align: left;
  font-size: 15px;
  color: var(--ink-c);
}
/* A session message ("Signed out.") becomes a strip with the amber "!" square. */
body.team-app #gateView #gateNotice:not(:empty) {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border: 1px solid var(--accent-c);
}
body.team-app #gateView #gateNotice:not(:empty)::before {
  content: "!";
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  background: var(--accent-c);
  color: var(--on-accent-c);
  font: 400 17px/1 var(--font-display);
}
/* 5.3 Doors */
body.team-app #gateView #gateWays { gap: 24px; align-items: stretch; }
body.team-app #gateView #signinForm,
body.team-app #gateView #clockPanel,
body.team-app #gateView #setupForm {
  gap: 16px;
  padding: 28px 24px;
  background: var(--panel-c);
  border: 1px solid var(--line-c);
  border-top-width: 3px;
  border-radius: 0;
}
body.team-app #gateView #signinForm { border-top-color: var(--ink-c); }
body.team-app #gateView #clockPanel,
body.team-app #gateView #setupForm { border-top-color: var(--accent-c); }
body.team-app #gateView .gate__role {
  margin: 0;
  font: 700 13px/1.3 var(--font-body);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--accent-c);
}
body.team-app #gateView .gate__tag {
  display: inline-block;
  margin-left: 8px;
  padding: 4px 8px;
  border: 1px solid var(--line-2-c);
  color: var(--text-c);
  font: 400 13px/1 var(--font-body);
  letter-spacing: 0.12em;
  vertical-align: middle;
}
body.team-app #gateView #signinForm h2,
body.team-app #gateView #clockPanel h2,
body.team-app #gateView #setupForm h2 {
  margin: 0;
  font: 400 28px/1 var(--font-display);
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--ink-c);
}
body.team-app #gateView .gate__panel .gate__lede,
body.team-app #gateView #signinForm .gate__lede,
body.team-app #gateView #clockPanel .gate__lede,
body.team-app #gateView #setupForm .gate__lede {
  margin: 0;
  font: var(--app-t-body);
  color: var(--text-c);
}
body.team-app #gateView .field label { font-size: 13px; }
body.team-app #gateView #signinEmail,
body.team-app #gateView #signinPassword,
body.team-app #gateView #setupPassword,
body.team-app #gateView #setupConfirm {
  min-height: 52px;
  border-radius: 0;
  font-size: 16px;
}
body.team-app #gateView .field__reveal { min-height: 44px; min-width: 64px; font-size: 13px; }
body.team-app #gateView .field__hint { font-size: 13px; color: var(--text-c); }
body.team-app #gateView #signinMsg,
body.team-app #gateView #setupMsg,
body.team-app #gateView #pinMsg {
  min-height: 1.4rem;
  font: 700 15px/1.35 var(--font-body);
  color: var(--bad);
}
body.team-app #gateView #signinBtn,
body.team-app #gateView #setupBtn,
body.team-app #gateView #setupCancel,
body.team-app #gateView #pinDone { min-height: 52px; border-radius: 0; }
body.team-app #gateView #signinBtn:disabled { opacity: 0.55; cursor: progress; }
body.team-app #gateView #gateFoot {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  text-align: left;
  color: var(--muted-c);
}
@media (min-width: 760px) {
  body.team-app #gateView #signinForm,
  body.team-app #gateView #clockPanel,
  body.team-app #gateView #setupForm { padding: 32px 28px; }
}
/* Phone: the two doors are a switch; one door at a time (class toggle, staff.css). */
@media (max-width: 759px) {
  body.team-app #gateView #gateSwitch { margin: 0; border: 1px solid var(--line-2-c); }
  body.team-app #gateView .gate__switch-tab {
    min-height: 56px;
    padding: 0 8px;
    color: var(--text-c);
    font: 400 17px/1 var(--font-display);
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }
  body.team-app #gateView .gate__switch-tab.is-on,
  body.team-app #gateView .gate__switch-tab[aria-selected="true"] {
    background: var(--accent-c);
    color: var(--on-accent-c);
  }
  body.team-app #gateView #gateTitle { font-size: clamp(28px, 8vw, 40px); }
}
/* 5.4 Keypad */
body.team-app #clockPanel .attendance-pin-action { margin: 0; gap: 8px; }
body.team-app #clockPanel .attendance-pin-action label {
  font: var(--app-t-label);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent-c);
}
body.team-app #clockPanel #pinDirection {
  width: 100%;
  min-height: 48px;
  padding: 0 12px;
  background: var(--bg-c);
  border: 1px solid var(--line-2-c);
  border-radius: 0;
  color: var(--ink-c);
  font: 400 16px/1.2 var(--font-body);
}
body.team-app #clockPanel #pinDirection:focus-visible { outline: 2px solid var(--accent-c); outline-offset: 2px; }
body.team-app #clockPanel .attendance-help,
body.team-app #clockPanel .attendance-note {
  margin: 0;
  font: var(--app-t-small);
  color: var(--text-c);
}
body.team-app #clockPanel #pinDots { margin: 4px 0; gap: 10px; }
body.team-app #clockPanel .pin-dot { width: 20px; height: 20px; border: 2px solid var(--line-2-c); }
body.team-app #clockPanel .pin-dot.is-on { background: var(--accent-c); border-color: var(--accent-c); }
body.team-app #clockPanel #pinPad button {
  border: 1px solid var(--line-2-c);
  border-radius: 0;
  background: var(--bg-c);
  color: var(--ink-c);
  font: 400 28px/1 var(--font-display);
  letter-spacing: 0.02em;
}
body.team-app #clockPanel #pinPad button[data-key="clear"],
body.team-app #clockPanel #pinPad button[data-key="enter"] {
  font-size: 15px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
body.team-app #clockPanel #pinPad button[data-key="clear"] { color: var(--text-c); }
body.team-app #clockPanel #pinPad button[data-key="enter"] {
  background: var(--accent-c);
  border-color: var(--accent-c);
  color: var(--on-accent-c);
}
/* Disabled keys (no action chosen yet, or busy): dashed + muted + the message. */
body.team-app #clockPanel #pinPad button:disabled,
body.team-app #clockPanel #pinPad button:disabled:hover {
  background: var(--bg-c);
  border-color: var(--line-2-c);
  border-style: dashed;
  color: var(--muted-c);
  cursor: not-allowed;
}
/* Busy: a 2px amber top rule while #pinMsg says what is happening. */
body.team-app #clockPanel #pinPad[aria-busy="true"] { box-shadow: inset 0 2px 0 var(--accent-c); }
/* Wrong PIN (js/app-shell.js adds .is-bad for 420ms on the exact refusal string). */
body.team-app #gateView #pinPad.is-bad {
  animation: app-shake 420ms var(--app-ease);
  box-shadow: inset 0 2px 0 var(--bad);
}
body.team-app #clockPanel #pinResult { min-height: var(--pin-pad-h, 302px); gap: 8px; }
body.team-app #clockPanel #pinResultName {
  font: 400 32px/1.05 var(--font-display);
  text-transform: uppercase;
  color: var(--ink-c);
}
body.team-app #clockPanel #pinResultWhat { font-size: 17px; line-height: 1.35; color: var(--ink-c); }
body.team-app #clockPanel #pinResultShift { font-size: 14px; line-height: 1.4; color: var(--text-c); }
body.team-app #clockPanel #pinBoardTitle {
  margin-top: 8px;
  font: var(--app-t-label);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted-c);
}
body.team-app #clockPanel #pinBoard { font-size: 14px; color: var(--text-c); }

/* ============================================================
   6.2 MOTION — keyframes (prefixed app-) and the reduced-motion switch
   ============================================================ */
@keyframes app-sheet-in {
  from { transform: translateY(24px); opacity: 0; }
  to { transform: none; opacity: 1; }
}
@keyframes app-pop {
  from { transform: scale(0.8); opacity: 0; }
  to { transform: none; opacity: 1; }
}
@keyframes app-rise {
  from { transform: translateY(8px); opacity: 0; }
  to { transform: none; opacity: 1; }
}
@keyframes app-shake {
  0%, 100% { transform: none; }
  20% { transform: translateX(-6px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(4px); }
}
@media (prefers-reduced-motion: reduce) {
  body.team-app * {
    animation-duration: 0ms !important;
    transition-duration: 0ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================
   6.3 FOCUS RINGS — one ring, amber; ink on amber fills; inset in the chrome
   ============================================================ */
body.team-app :is(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--accent-c);
  outline-offset: 2px;
}
body.team-app :is(.rail__tabs .tab, .app-dock button, .tabsheet__cell, .rail__foot-item, .rail__brand-link, .app-alert):focus-visible {
  outline-offset: -2px;
}
body.team-app :is(.btn--primary, .rg-btn--primary, #signinBtn, #pinPad [data-key="enter"], #appFab, .app-dock button[aria-current="page"], #onboardGo):focus-visible {
  outline-color: var(--ink-c);
}
body.team-app #dashTitle:focus { outline: none; }
body.team-app :focus:not(:focus-visible) { outline: none; }

/* ============================================================
   6.5 PRINT — no chrome; the window is the scroller so payslips print as today.
   (Specificity matches the rules above and this block is last, so no !important.)
   ============================================================ */
@media print {
  body.team-app.is-authed #tabRail,
  body.team-app.is-authed #dashHead,
  body.team-app.is-authed #appFab,
  body.team-app.is-authed #appAlerts,
  body.team-app #appPalette,
  body.team-app .app-dock,
  body.team-app #tabSheet,
  body.team-app #onboardBanner,
  body.team-app .appbar { display: none; }
  body.team-app.is-authed main.staff { padding: 0; }
  body.team-app.is-authed :is(.panel, #onboardBanner) { padding-inline: 0; max-width: none; }
}
