/* EVO TrustGuard — page-timeclock.css
 *
 * Owned by:    timeclock.html (admin-only Timeclock, C145-S8)
 * Category:    admin shell page (PERMANENTLY DARK — data-theme="dark" is
 *              pinned statically on <html>; no light variant, no toggle, no
 *              prefers-color-scheme branch. Matches the theme posture of the
 *              five sibling admin pages exactly.)
 * Cascade:     tokens → base → utilities → components → portal-chrome →
 *              shared → shared-themes → page-admin (admin shell layer) → page
 * Edit policy: rules unique to this page only. The shared admin-shell chrome
 *              (.ash-*, including .ash-gate) lives in /css/page-admin.css —
 *              see /css/AGENTS.md "Admin dark-glass shell".
 *
 * Design language: the same dark-glass vocabulary as page-sales-metrics.css /
 * page-sales-pipeline.css — 3G.1 Glass tokens (--tier1-bg / --hairline /
 * --shadow-float / --glass-surface) plus the platform status hues. Existing
 * tokens ONLY; the two page-scoped custom properties below follow the rule-2
 * --sp-* / --om-* / --sm-* precedent.
 *
 * THE TIMECARD FOLDS, THE ANSWER DOES NOT. Each day card collapses to its own
 * header line, and that line IS the toggle (.tc-day-head is a real <button>).
 * The day total stays visible in the collapsed state by design — a folded card
 * must still answer "how long did I work that day" without being opened. See
 * the .tc-day-head block for why the hit target is built from a full bleed into
 * the card's own padding rather than from min-height.
 *
 * THE STATE MUST BE UNMISREADABLE. The single hardest requirement on this
 * page is that a person can never be wrong about whether they are on the
 * clock. So state is carried by THREE redundant signals at once — a coloured
 * dot, a word ("Clocked in" / "On break" / "Clocked out"), and the presence or
 * absence of the running meters — never by colour alone. Colour is the last
 * of the three, not the first, which is also what makes it legible to anyone
 * who cannot distinguish the hues.
 */
:root {
  /* The clock's state axis. Green = time is accruing, amber = paused on a
     break, grey = nothing is being recorded. Literal rgba of an existing
     token hue is the sanctioned C103 wash pattern (a --status-*-wash would
     work for two of the three, but not for the muted "off" state, and one
     consistent construction beats a mixed one). */
  --tc-on-edge:    rgba(34, 197, 94, 0.45);
  --tc-break-edge: rgba(245, 158, 11, 0.45);
  /* Badge ground for a RUNNING break, the amber counterpart to the platform's
     --status-active-wash. Declared here rather than borrowed from
     page-sales-metrics.css's --sm-warn-wash: that stylesheet is not loaded on
     this page, so the reference would silently fall back on every render, and
     this file's edit policy is rules unique to this page. */
  --tc-break-wash: rgba(245, 158, 11, 0.14);
}

/* ── App container — sits inside the M8.1 admin shell grid ── */
.tc-app {
  max-width: 860px;
  margin: 0 auto;
  width: 100%;
  padding: var(--space-5) var(--space-5) calc(var(--space-8) + env(safe-area-inset-bottom));
}

/* ── Header ── */
.tc-header {
  display: flex;
  align-items: flex-end;
  gap: var(--space-3-5);
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
}
.tc-header-titles { min-width: 200px; }
.tc-title {
  font-family: 'DM Serif Display', serif;
  font-size: var(--text-3xl);
  color: var(--text);
  margin: 0;
  font-weight: var(--weight-regular);
}
.tc-subtitle {
  color: var(--text-muted);
  font-size: var(--text-md);
  margin: var(--space-1) 0 0;
}

/* ── REGION A — the clock ────────────────────────────────────────────────── */
.tc-clock {
  background: var(--tier1-bg);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-2xl);
  box-shadow: var(--shadow-float);
  padding: var(--space-5);
  margin-bottom: var(--space-6);
  /* The 4px accent edge reads the state at a glance from anywhere on the
     page, including when the meters have scrolled out of view. */
  border-left: 4px solid var(--border-strong);
}
/* State classes are set on this element by js/page-timeclock.js rather than
   derived with :has(). A plain class so there is no browser-support cliff —
   the same call page-call-mode.css records for the same reason. */
.tc-clock.is-state-in    { border-left-color: var(--tc-on-edge); }
.tc-clock.is-state-break { border-left-color: var(--tc-break-edge); }

.tc-clock-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 120px;
}

.tc-state-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.tc-state-dot {
  width: 10px;
  height: 10px;
  border-radius: var(--radius-pill);
  background: var(--text-faint);
  flex: none;
}
.tc-state-dot.is-in    { background: var(--status-active); }
.tc-state-dot.is-break { background: var(--amber); }
.tc-state-dot.is-out   { background: var(--text-faint); }

.tc-state-label {
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--text);
  letter-spacing: 0.2px;
}

.tc-clock-hint {
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: 1.5;
  margin: var(--space-2) 0 0;
  max-width: 60ch;
}
.tc-clock-hint strong { color: var(--text); font-weight: 600; }

/* The auto-close disclosure. Given a warn-toned left edge so it reads as
   "this will happen", not as a footnote — the whole point is that clocking
   out during a break is never a silent side effect. */
.tc-clock-note {
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: 1.5;
  margin: var(--space-3) 0 0;
  padding-left: var(--space-3);
  border-left: 2px solid var(--tc-break-edge);
  max-width: 60ch;
}

/* ── Live meters ── */
.tc-meters {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-2-5);
  margin-top: var(--space-4);
}
.tc-meter {
  background: var(--glass-surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-3);
  min-width: 0;
}
.tc-meter-label {
  color: var(--text-muted);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin-bottom: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tc-meter-value {
  /* Tabular figures so a ticking clock does not shimmy as digits change. */
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}
/* Which meter is actually advancing right now. Redundant with the state word
   above it — a second, quieter confirmation, never the only signal.
   The hue follows the CARD's state, not merely "something is counting": green
   means worked time is accruing, amber means you are on a break. Painting the
   break counter green would have left one card showing an amber dot, an amber
   edge, an amber note rule and a green number. */
.tc-meter.is-running .tc-meter-value { color: var(--status-active); }
.tc-meter.is-paused  .tc-meter-value { color: var(--text-muted); }
.is-break .tc-meter.is-running .tc-meter-value { color: var(--amber); }

/* ── Actions ── */
.tc-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2-5);
  margin-top: var(--space-4);
}
.tc-btn {
  font-family: inherit;
  font-size: var(--text-md);
  font-weight: 600;
  border-radius: var(--btn-radius);
  padding: var(--space-3) var(--space-5);
  cursor: pointer;
  border: 1px solid transparent;
  /* 48px — the LOCKED C70-C PAGE-PRIMARY tier, not the 44px touch floor and
     not the 40px form-adjacent tier. Every button on this page is a page-level
     action tapped one-handed, often in a hurry, and a mis-tap costs a punch. */
  min-height: 48px;
  transition: background 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;
}
.tc-btn-lg { flex: 1 1 160px; }
.tc-btn-primary {
  background: var(--red);
  color: var(--white);
}
.tc-btn-primary:hover:not(:disabled) { background: var(--red-hover); }
.tc-btn-secondary {
  background: transparent;
  color: var(--text);
  border-color: var(--border-strong);
}
.tc-btn-secondary:hover:not(:disabled) { border-color: var(--text-muted); }
.tc-btn:disabled { opacity: 0.5; cursor: default; }
.tc-btn:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}

.tc-clock-error .tc-clock-state {
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--text);
  margin: 0;
}
.tc-clock-error .tc-btn { margin-top: var(--space-4); }

/* ── REGION B — the timecard ─────────────────────────────────────────────── */
.tc-sec-head { margin-bottom: var(--space-3-5); }
/* TC-EDIT1 — "Add a missed shift" sits beside the title and wraps under it on
   a narrow screen. */
.tc-sec-head.has-action {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.tc-sec-titles { min-width: 0; flex: 1 1 260px; }
.tc-add-shift { flex: none; }
.tc-sec-title {
  font-family: 'DM Serif Display', serif;
  font-size: var(--text-xl);
  color: var(--text);
  margin: 0;
  font-weight: var(--weight-regular);
}
.tc-sec-sub {
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: 1.5;
  margin: 2px 0 0;
  max-width: 66ch;
}

/* ── Week ── */
.tc-week { margin-bottom: var(--space-5); }
.tc-week-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding-bottom: var(--space-2);
  margin-bottom: var(--space-2-5);
  border-bottom: 1px solid var(--hairline);
}
.tc-week-title {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin: 0;
}
.tc-week-total {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}

/* ── Day ── */
.tc-day {
  background: var(--tier1-bg);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-float);
  padding: var(--space-3-5);
  margin-bottom: var(--space-2-5);
}
/* THE HEADER LINE IS THE TOGGLE. A real <button>, so Enter and Space activate
   it with no keyboard JS of our own — the page wires 'click' only, because a
   keydown handler would fire ALONGSIDE the click the browser synthesises from
   Enter and toggle the card twice.

   Unstyled: css/base.css already strips background / border / cursor and sets
   `font: inherit`, so only the box, the alignment, text-align and the
   appearance pair are restated here — the last of those because iOS Safari
   still paints its own control chrome through a bare `background: none`
   (page-admin.css's .tcw-bar ships the identical pair on the identical class
   of admin-shell button). The declarations above the reset group are the
   ORIGINAL div rules, byte-for-byte — the row must render exactly as it did
   before.

   THE FULL-BLEED IS A TOUCH TARGET, NOT A LAYOUT CHANGE. The row's natural
   height is 38.5px (measured), 5.5px under the 44px floor. `min-height: 44px`
   would have paid for that by dropping ~6px of dead space BELOW a
   baseline-aligned row, making every card taller. Instead the button absorbs
   the card's own 14px padding on three sides — negative margin out, equal
   padding back in — so the hit box is 52.5px while the text does not move one
   pixel. padding-bottom stays 0 so .tc-shift's margin-top keeps the body
   exactly where it was. .tc-day's padding is a flat --space-3-5 at every
   width, so the calc holds at 375px too.

   The min-height below is INERT today (14 + 38.5 = 52.5px) and is kept only as
   a floor: if the date stack ever collapses to a single line the padding alone
   would no longer clear 44px. It is a backstop, not the mechanism — the
   paragraph above is why it must not be the mechanism. */
.tc-day-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin: calc(var(--space-3-5) * -1) calc(var(--space-3-5) * -1) 0;
  padding: var(--space-3-5) var(--space-3-5) 0;
  width: calc(100% + var(--space-3-5) * 2);
  min-height: 44px;
  text-align: left;
  appearance: none;
  -webkit-appearance: none;
}
/* Inset ring — the button is full-bleed to the card's inner edge, so a
   positive offset would draw the outline outside the card entirely. */
.tc-day-head:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: -2px;
}
.tc-day-date {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
/* Total + chevron as ONE right-hand group. As a third direct child of the
   space-between row the total would have been pushed to the middle. */
.tc-day-right {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: none;
}
.tc-day-weekday {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text);
}
.tc-day-full {
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.tc-day-total {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}
/* base.css sets `svg { height: auto }`, so both axes are stated. */
.tc-day-chev {
  width: 16px;
  height: 16px;
  flex: none;
  color: var(--text-muted);
  transition: transform 0.15s ease;
}
.tc-day-head.is-expanded .tc-day-chev { transform: rotate(180deg); }

/* The shifts. Hidden, NEVER removed — the open shift's live worked figure
   (#tcRowWorked) lives in here and must keep receiving its per-second update
   while the card is shut, so that reopening shows a current number rather than
   one frozen at the moment it was closed.

   The explicit display:none is the house [hidden]-vs-display guard (see
   page-call-mode.css). It is belt-and-braces today because .tc-day-body has no
   display rule of its own; it is here so that adding one later cannot silently
   un-hide every collapsed card. */
.tc-day-body[hidden] { display: none; }

/* ── Shift ── */
.tc-shift {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--hairline);
}
/* An OPEN shift is marked, not merely different — it gets the same green
   accent as the live clock so the two read as one fact in two places. */
.tc-shift.is-open {
  border-left: 3px solid var(--tc-on-edge);
  padding-left: var(--space-3);
  margin-left: calc(var(--space-3) * -1);
}
/* Centred, not baseline: the row now carries a 44px Edit button (TC-EDIT1),
   and baseline alignment would hang the punch text off the button's label. */
.tc-shift-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.tc-shift-right {
  display: flex;
  align-items: center;
  gap: var(--space-2-5);
  margin-left: auto;
}
/* The correction entry point. Quiet on purpose — a column of red buttons
   would out-shout the punch buttons, which are the page's real actions — but
   a full 44px touch target. */
.tc-shift-edit {
  -webkit-appearance: none;
  appearance: none;
  min-height: 44px;
  min-width: 44px;
  padding: 0 var(--space-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--btn-radius);
  background: transparent;
  color: var(--text);
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.15s ease;
}
.tc-shift-edit:hover { border-color: var(--text-muted); }
.tc-shift-edit:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}
.tc-shift-punch {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  font-size: var(--text-md);
  color: var(--text);
}
.tc-shift-worked {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}
.tc-shift-note {
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: 1.5;
  margin: var(--space-2) 0 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* The in-progress marker — a word, not just a colour. */
.tc-inprogress {
  display: inline-block;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--status-active);
  background: var(--status-active-wash);
  border-radius: var(--radius-pill);
  padding: 1px var(--space-2);
  letter-spacing: 0.3px;
  white-space: nowrap;
}

/* ── Breaks ── */
.tc-breaks {
  list-style: none;
  margin: var(--space-2) 0 0;
  padding: 0;
}
/* --text-muted, NOT --text-faint: #6a6a6a on the card surface is ~3.3:1 at
   11px and fails WCAG AA. These two rules carry real information — "2 breaks",
   "No breaks" distinguishes none-taken from not-shown — so they must be
   readable. --text-faint stays only on .tc-state-dot, which is decorative and
   fully redundant with the state word beside it. */
.tc-breaks-head {
  color: var(--text-muted);
  margin: var(--space-2) 0 2px;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin-bottom: 2px;
}
.tc-break {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 2px 0 2px var(--space-3);
  border-left: 2px solid var(--border);
}
.tc-break.is-open { border-left-color: var(--tc-break-edge); }
/* Same rule as the meters above: green is reserved for time accruing as
   WORKED. A running BREAK is amber, so its pill matches its own row's edge
   instead of borrowing the shift's colour. */
.tc-break.is-open .tc-inprogress {
  color: var(--amber);
  background: var(--tc-break-wash);
}
.tc-break-time {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  font-size: var(--text-sm);
  color: var(--text-muted);
}
.tc-break-span {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  font-size: var(--text-sm);
  color: var(--text-muted);
  white-space: nowrap;
}
.tc-nobreaks {
  color: var(--text-muted);
  font-size: var(--text-xs);
  margin: var(--space-2) 0 0;
}

/* ── Notes / empty / error ── */
.tc-note {
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: 1.5;
  margin: var(--space-5) 0 0;
  padding-top: var(--space-3-5);
  border-top: 1px solid var(--hairline);
  max-width: 70ch;
}

/* Reads as a BEGINNING, never as an error — dashed border, muted copy, no
   warn hue anywhere. The error variant below is the one that gets a solid
   warn edge, so the two can never be mistaken for each other. */
.tc-empty {
  background: var(--glass-surface);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-3-5);
}
.tc-empty p {
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: 1.5;
  margin: 0;
  max-width: 60ch;
}
.tc-empty p + p { margin-top: var(--space-2); }
.tc-empty strong { color: var(--text); }
.tc-empty.is-error {
  border-style: solid;
  border-color: var(--danger);
}

/* ── EDIT SHEET (TC-EDIT1) ───────────────────────────────────────────────── *
 * Fix a shift from the timeclock instead of from the database. The markup is
 * static at the bottom of timeclock.html; js/page-timeclock.js fills and wires
 * it.
 *
 * THE PLATFORM'S TIER-3 SHEET CONTRACT, restated for a form. /css/_lib/
 * dialog.css is the reference: a 0.55 scrim, a glass surface built only from
 * the 3G.1 Glass tokens (LOCKED C97-A), a BOTTOM SHEET below 640px (the
 * LOCKED-C101 breakpoint) and a centred card at and above it, the opaque-tint
 * fallback where backdrop-filter is missing, and reduced motion honoured. It
 * is not a TG.dialog because dialog.js renders a title, a message and buttons
 * only; a shift needs inputs. The delete confirmation IS the shared dialog.
 *
 * Differences from dialog.css, each on purpose:
 *   - wider card (560px, not 420px) — two date/time pairs side by side;
 *   - a scrolling body between a fixed head and a fixed foot, so Save is
 *     always reachable however many breaks a shift has;
 *   - z-index var(--z-modal), the same layer; the delete dialog opens later in
 *     the DOM, so it stacks above this sheet, and the toast (--z-toast) above
 *     both. */
.tc-sheet-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: rgba(0, 0, 0, 0.55);
  opacity: 0;
  transition: opacity 0.2s ease;
  /* Closing takes up to 360ms before the hidden attribute lands; a fading
     scrim must not swallow the taps meant for the page (dialog.css:53). */
  pointer-events: none;
}
/* The house [hidden]-vs-display guard: display:flex above would otherwise
   beat the hidden attribute and leave an invisible scrim eating every tap. */
.tc-sheet-overlay[hidden] { display: none; }
.tc-sheet-overlay.is-open { opacity: 1; pointer-events: auto; }
/* Focus guards (see onSheetGuardFocus): focusable, invisible, and out of the
   flex row so they cannot nudge the sheet. */
.tc-focus-guard {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
}

/* Class-based scroll lock (see openSheet in page-timeclock.js for why it is
   not an inline style). */
html.tc-scroll-lock,
html.tc-scroll-lock body { overflow: hidden; }

.tc-sheet {
  width: 100%;
  max-width: 640px;
  max-height: 92vh;
  max-height: 92dvh;
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  background: var(--tier3-tint);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  border: 1px solid var(--glass-edge);
  border-bottom: none;
  box-shadow: var(--glass-shadow), inset 0 1px 0 var(--edge-highlight);
  color: var(--text);
  transform: translateY(100%);
  transition: transform 0.3s ease;
}
.tc-sheet:focus { outline: none; }
.tc-sheet-overlay.is-open .tc-sheet { transform: translateY(0); }
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .tc-sheet { background: var(--tier3-tint-opaque); }
}

.tc-sheet-head {
  padding: var(--space-5) var(--space-5) var(--space-3);
  flex: none;
}
.tc-sheet-title {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  color: var(--text);
}
.tc-sheet-sub {
  margin: var(--space-1) 0 0;
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: 1.5;
}
.tc-sheet-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--space-2) var(--space-5) var(--space-4);
}
.tc-sheet-foot {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-2-5);
  padding: var(--space-3) var(--space-5) calc(var(--space-4) + env(safe-area-inset-bottom));
  border-top: 1px solid var(--glass-edge);
}
.tc-sheet-foot-main {
  display: flex;
  gap: var(--space-2-5);
  margin-left: auto;
}
.tc-sheet-foot [hidden] { display: none; }

/* Destructive — the contained tinted-red treatment (--btn-destructive-*), the
   same tokens as dialog.css's .tg-dlg-danger. */
.tc-btn-danger {
  background: var(--btn-destructive-bg);
  border: var(--btn-destructive-border);
  color: var(--btn-destructive-text);
}
/* Last in the markup (last in tab order), drawn at the LEFT of the row. */
.tc-sheet-foot .tc-btn-danger { order: -1; }
.tc-btn-danger:hover:not(:disabled) { filter: brightness(1.1); }

@media (min-width: 640px) {
  .tc-sheet-overlay { align-items: center; }
  .tc-sheet {
    width: calc(100% - var(--space-5) * 2);
    max-width: 560px;
    max-height: 88vh;
    max-height: 88dvh;
    border-radius: var(--radius-xl);
    border-bottom: 1px solid var(--glass-edge);
    transform: scale(0.96);
    transition: transform 0.2s ease;
  }
  .tc-sheet-overlay.is-open .tc-sheet { transform: scale(1); }
  .tc-sheet-foot { padding-bottom: var(--space-4); }
}

/* Problem summary — a solid danger edge, so it can never read as a hint. */
.tc-sheet-errors {
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-3-5);
  border: 1px solid var(--danger);
  border-radius: var(--radius-lg);
  background: var(--danger-wash);
}
.tc-sheet-errors[hidden] { display: none; }
.tc-sheet-errors:focus { outline: none; }
.tc-sheet-errors:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
.tc-sheet-errors-lead {
  margin: 0 0 var(--space-1);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
}
.tc-sheet-errors-list {
  margin: 0;
  padding-left: var(--space-4);
  color: var(--text);
  font-size: var(--text-sm);
  line-height: 1.5;
}
.tc-sheet-errors-list li + li { margin-top: var(--space-1); }

.tc-fs {
  border: 0;
  margin: 0 0 var(--space-4);
  padding: 0;
  min-width: 0;
}
.tc-fs-legend {
  padding: 0;
  margin-bottom: var(--space-2);
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-muted);
}

/* A date and a time side by side, at every width including 375px. */
.tc-dt {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-2-5);
}
.tc-dt[hidden] { display: none; }
.tc-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.tc-field-label {
  font-size: var(--text-sm);
  color: var(--text-muted);
}
/* Tier-2 recessed wells (the .field input recipe in page-admin.css). 16px
   text is the iOS zoom threshold; 48px matches the page's button tier. The
   native picker glyph follows shared-themes.css's dark color-scheme. */
.tc-input {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  min-width: 0;
  min-height: 48px;
  padding: 0 var(--space-3);
  font-family: inherit;
  font-size: var(--text-input);
  font-variant-numeric: tabular-nums;
  color: var(--text);
  background: var(--tier2-bg);
  border: 1px solid var(--hairline);
  box-shadow: var(--tier2-inset);
  border-radius: var(--radius-md);
}
.tc-input:focus { outline: none; border-color: var(--red); }
.tc-input[aria-invalid="true"] { border-color: var(--danger); }
/* An invalid field still has to SHOW focus; the invalid border alone would
   win the cascade and leave no visible change when it is focused. */
.tc-input[aria-invalid="true"]:focus {
  border-color: var(--red);
  box-shadow: var(--tier2-inset), 0 0 0 2px var(--red);
}
/* While a save is in flight the fieldsets are disabled (setSheetBusy). */
.tc-input:disabled,
.tc-check input:disabled { opacity: 0.6; cursor: default; }

.tc-check {
  display: flex;
  align-items: center;
  gap: var(--space-2-5);
  min-height: 44px;
  font-size: var(--text-md);
  color: var(--text);
  cursor: pointer;
}
.tc-check[hidden] { display: none; }
.tc-check input {
  width: 20px;
  height: 20px;
  margin: 0;
  flex: none;
  accent-color: var(--red);
}
.tc-check input:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
#tcOutRow { margin-top: var(--space-1); }

/* One break. */
.tc-brk {
  background: var(--glass-surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-2) var(--space-3) var(--space-3);
  margin-bottom: var(--space-2-5);
}
.tc-brk.is-invalid { border-color: var(--danger); }
.tc-brk-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-1);
}
.tc-brk-title {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text);
}
.tc-brk-remove {
  -webkit-appearance: none;
  appearance: none;
  min-height: 44px;
  min-width: 44px;
  padding: 0 var(--space-2-5);
  margin-right: calc(var(--space-2-5) * -1);
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  border-radius: var(--btn-radius);
  cursor: pointer;
}
.tc-brk-remove:hover:not(:disabled) { color: var(--danger); }
.tc-brk-remove:focus-visible { outline: 2px solid var(--red); outline-offset: -2px; }
.tc-brk-remove:disabled { opacity: 0.5; cursor: default; }
.tc-brk .tc-check { margin-top: var(--space-1); }
.tc-brk [data-brk-end] { margin-top: var(--space-1); }
.tc-brk-error {
  margin-top: var(--space-2-5);
  padding-left: var(--space-3);
  border-left: 2px solid var(--danger);
}
.tc-brk-error[hidden] { display: none; }
.tc-brk-error-msg {
  margin: 0 0 var(--space-2);
  color: var(--text);
  font-size: var(--text-sm);
  line-height: 1.5;
}
.tc-sheet-nobreaks {
  margin: 0 0 var(--space-2-5);
  color: var(--text-muted);
  font-size: var(--text-sm);
}
.tc-sheet-nobreaks[hidden] { display: none; }

/* ── Responsive — 375px is the design target for this page ── */
@media (max-width: 480px) {
  .tc-app { padding-left: var(--space-3-5); padding-right: var(--space-3-5); }
  /* Three meters do not fit at 375px without truncating a running clock, and
     a truncated clock is worse than a stacked one. */
  .tc-meters { grid-template-columns: repeat(2, 1fr); }
  .tc-meters .tc-meter:last-child { grid-column: 1 / -1; }
  /* Full-width stacked buttons — a mis-tap here costs a punch. */
  .tc-btn-lg { flex: 1 1 100%; }
  .tc-actions .tc-btn { width: 100%; }
  .tc-add-shift { width: 100%; }
  /* Sheet: padding tightened to the page's 375px gutter; Cancel and Save
     share the row, Delete takes its own full-width row BELOW them so the
     destructive action is never where a thumb reaches for Save. */
  .tc-sheet-head { padding-left: var(--space-3-5); padding-right: var(--space-3-5); }
  .tc-sheet-body { padding-left: var(--space-3-5); padding-right: var(--space-3-5); }
  .tc-sheet-foot { padding-left: var(--space-3-5); padding-right: var(--space-3-5); }
  .tc-sheet-foot-main { width: 100%; margin-left: 0; }
  .tc-sheet-foot-main .tc-btn { flex: 1 1 0; }
  .tc-sheet-foot .tc-btn-danger { order: 0; width: 100%; }
  .tc-sheet-addbrk { width: 100%; }
}

/* A ticking clock is motion. Honour a reduced-motion preference by removing
   the button and chevron transitions; the tickers themselves are information,
   not decoration, and are left alone. The chevron still ROTATES to show the
   state — only the animation between the two positions is dropped. The edit
   sheet cuts in instead of sliding or scaling. */
@media (prefers-reduced-motion: reduce) {
  .tc-btn,
  .tc-day-chev,
  .tc-shift-edit { transition: none; }
  .tc-sheet-overlay { transition: opacity 0.001s linear; }
  .tc-sheet,
  .tc-sheet-overlay.is-open .tc-sheet { transition: none; transform: none; }
}
