/* SPIGI GM admin portal — the whole stylesheet (plan §19.2).
   One file. System fonts, no web font, no image, no @import, no CDN — the CSP
   (`default-src 'none'; style-src 'self'`) would block them anyway, and the GM opens this
   on hotel wifi. Colour is never the only carrier of meaning: every badge pairs its colour
   with a word. */

/* twice-daily design D9 (2026-08-21): 13px x 0.9. This is the base for every `rem` length
   in this file, and `body` below carries the same absolute value -- both are required, or
   everything that inherits from body keeps the old size. No `rem` multiplier moves. */
:root {
  font-size: 11.7px;
  color-scheme: light;
  --bg: #f7f9fc;
  --surface: #ffffff;
  --ink: #16283c;
  --muted: #5a6b7f;
  --line: #d9e2ec;
  --accent: #0057b8;
  --accent-hover: #00458f;
  --navy: #002f61;
  --accent-ink: #ffffff;
  --warn-bg: #fff4d6;
  --warn-ink: #704d00;
  /* Early clock-in (portal v3 D.3). Its OWN pair, not a reuse of --warn-*: the warning
     banner and an infraction badge are different meanings, and one must not be able to
     restyle the other. True orange, distinct from the amber above and the red below;
     ink-on-background contrast is about 7.4:1. Light-only, like the rest of this palette. */
  --early-bg: #ffedd8;
  --early-ink: #8a4b00;
  /* Meeting block (owner ruling 2026-08-16). Its OWN tokens, not a reuse of --early-* or the
     department pill: a Meeting chip is a fact about the SCHEDULE, not a status verdict, and
     must not read as one. */
  --meeting-bg: #eef1f8;
  --meeting-ink: #40507a;
  /* Role mismatch (portal v3 F). Its OWN token, not a reuse of --early-* or --bad-*: an
     Early status BADGE and a "this shift is not one of the roles this department code
     covers" hint are different meanings, and one must not be able to restyle the other.
     Decoration only — the words "Scheduled for <position>" carry the meaning, in the title
     attribute, in a visually-hidden span beside the pill, and on the mobile card, so colour
     is never the only signal. */
  --mismatch-underline: #c2410c;
  --bad-bg: #fce8e6;
  --bad-ink: #b3261e;
  --ok-bg: #e7f4eb;
  --ok-ink: #1d7a3e;
  --scheduled-tint: #edf2f9;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 11.7px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
        Arial, sans-serif;
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: 0.5rem;
  top: 0.5rem;
  z-index: 10;
  background: var(--surface);
  padding: 0.5rem 0.75rem;
  border: 2px solid var(--accent);
  border-radius: 6px;
}

.badge {
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: var(--warn-bg);
  color: var(--warn-ink);
  border: 1px solid currentColor;
}
.badge.bad   { background: var(--bad-bg);   color: var(--bad-ink); }
.badge.ok    { background: var(--ok-bg);    color: var(--ok-ink); }
/* Not-signed v3 notice status (portal v3 C.6, Task 16). Same colours `.badge` already
   defaults to, stated explicitly per this file's own convention: a status colour is never
   left to inherit the base rule, so a future change to `.badge` cannot silently restyle it. */
.badge.warn  { background: var(--warn-bg);  color: var(--warn-ink); }
/* Early clock-in (portal v3 D.3). Stated explicitly rather than relying on `.badge`'s own
   amber default, so a future change to the base rule cannot silently restyle a status.
   Colour is never the only signal — the badge carries the word "Early". */
.badge.early { background: var(--early-bg); color: var(--early-ink); }

form.inline { margin: 0; }

button {
  font: inherit;
  padding: 0.4rem 0.8rem;
  border-radius: 6px;
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--accent-ink);
  cursor: pointer;
}
button.quiet { background: transparent; color: var(--ink); border-color: var(--line); }
/* Inside the dark sidebar chrome, --ink (near-black) is invisible; the sign-out button
   must borrow the sidebar's own text/line colors (caught in the live browser pass). */
.sidebar button.quiet { color: var(--sidebar-ink); border-color: var(--sidebar-line); }

main {
  max-width: 96rem;
  margin: 0 auto;
  padding: 1.25rem 1rem 3rem;
}

h1 { font-size: 1.4rem; margin: 0 0 0.75rem; }
h2 { font-size: 1.1rem; margin: 1.5rem 0 0.5rem; }
p.muted { color: var(--muted); }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 1rem 1.15rem;
  margin: 0 0 1rem;
}
.card.narrow { max-width: 26rem; }

.notice { border-left: 4px solid var(--accent); }
.notice.error { border-left-color: var(--bad-ink); background: var(--bad-bg);
                color: var(--bad-ink); }
.notice.info  { border-left-color: var(--warn-ink); background: var(--warn-bg);
                color: var(--warn-ink); }

label { display: block; margin: 0.75rem 0 0.25rem; font-weight: 600; }
input[type="email"], input[type="password"], input[type="text"], input[type="date"] {
  width: 100%;
  font: inherit;
  padding: 0.45rem 0.55rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg);
  color: var(--ink);
}

:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

/* Deliberately `rem`, not px: these ride the root, so the D9 base-size change scales the
   dense table with everything else and no multiplier here had to move. */
table { border-collapse: collapse; width: 100%; font-size: 0.92rem; }
th, td { text-align: left; padding: 0.32rem 0.38rem; border-bottom: 1px solid var(--line); }
th { font-size: 0.96rem; font-weight: 700; }
tbody tr:nth-child(even) { background: color-mix(in srgb, var(--surface) 60%, var(--bg)); }
td.num { text-align: left; font-variant-numeric: tabular-nums; }

th a { color: inherit; text-decoration: none; white-space: nowrap; }
th a:hover { text-decoration: underline; }

.table-scroll { overflow-x: auto; }

/* ── v2 tokens (design §4.1) ───────────────────────────────────────────────── */
:root {
  --muted-bg: #edf2f9;
  --muted-ink: #5a6b7f;
  --sidebar-bg: var(--navy);
  --sidebar-ink: #dfe7f0;
  --sidebar-line: #174f85;
  --sidebar-active-bg: var(--accent);
  --space-1: 0.25rem; --space-2: 0.5rem; --space-3: 0.75rem;
  --space-4: 1rem;    --space-6: 1.5rem; --space-8: 2rem;
}
/* The sidebar is deliberately dark chrome in BOTH themes (design §4.1): a fixed visual
   anchor the GM can navigate by muscle memory whatever the system theme is doing. */

.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  border: 0;
}

.shell { display: flex; align-items: flex-start; min-height: 100vh; }

/* portal v3.1 directive 1 — the SIGNED-OUT shell. With no principal there is no sidebar, so
   `.shell` has a single flex child and `.app-main`'s `flex: 1 1 auto` stretched one narrow
   card against the top-left corner of an empty viewport. Centring is a property of the shell,
   not of sign_in.html: `base.html` emits this modifier wherever `principal` is absent, so the
   sign-in page and every anonymous error page centre identically and neither needs its own
   rule. 28rem = `.card.narrow`'s 26rem plus `.app-main`'s two 1rem side paddings, so the card
   fills the centred column exactly rather than sitting left of its middle. */
.shell--anon { align-items: center; justify-content: center; }
.shell--anon .app-main { flex: 0 1 auto; width: 100%; max-width: 28rem; }

.sidebar {
  flex: 0 0 15rem; width: 15rem; align-self: stretch;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--space-4);
  padding: var(--space-4) var(--space-3);
  background: var(--sidebar-bg); color: var(--sidebar-ink);
  border-right: 1px solid var(--sidebar-line);
}
.sidebar__brand { font-weight: 700; letter-spacing: 0.06em; padding: 0 var(--space-2); }
.nav-group { display: flex; flex-direction: column; gap: var(--space-1); }
.nav-group__label {
  font-size: 0.85rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted-ink); padding: 0 var(--space-2) var(--space-1);
}
.nav-link {
  display: block; padding: var(--space-2) var(--space-3); border-radius: 8px;
  color: var(--sidebar-ink); text-decoration: none;
}
.nav-link:hover { background: rgb(255 255 255 / 8%); }
.nav-link--active { background: var(--sidebar-active-bg); font-weight: 700; }
.nav-link--quiet { font-size: 0.9rem; }
.sidebar__foot {
  margin-top: auto; border-top: 1px solid var(--sidebar-line);
  padding-top: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2);
}
.sidebar__who { font-size: 0.85rem; overflow-wrap: anywhere; }
.sidebar__role { font-size: 0.85rem; letter-spacing: 0.08em; color: var(--muted-ink); }

/* twice-daily design D9 (2026-08-21): 82rem -> 96rem so the 11-column Timecards table fits at
   1280px with no horizontal scroll. 96 x 11.7 = 1123px, deliberately WIDER than the ~1089px a
   1280px viewport leaves after the 15rem sidebar -- so at 1280px the viewport is the limit and
   this cap does not bind until ~1299px, while still capping the column on a wide screen.
   Mirrored by `main`'s own rule above; base.html:63 is <main id="main" class="app-main">, so
   both match the same element and must agree. `.shell--anon .app-main`'s 28rem is unrelated
   and unchanged. */
/* QA finding A1, second half (2026-08-22, measured live on mobile): `.shell` is a flex row and a
   flex item's default `min-width: auto` lets `main` grow to its content's min-content width,
   so a wide table pushed the layout viewport to 483px even with the card scrolling. `min-width: 0`
   lets `main` shrink to the screen and the `.table-scroll` card scrolls instead. */
.app-main { flex: 1 1 auto; min-width: 0; max-width: 96rem; padding: var(--space-6) var(--space-4) var(--space-8); }

.badge.muted { background: var(--muted-bg); color: var(--muted-ink); }
.empty-state { color: var(--muted); text-align: center; padding: var(--space-8) 0; }
/* ── mobile drawer (design §1.5) — pure CSS, no JS, works under `default-src 'none'` ── */
.nav-toggle-input { position: absolute; opacity: 0; pointer-events: none; }
.nav-toggle-btn { display: none; }
.nav-scrim { display: none; }
.nav-toggle-input:focus-visible ~ .shell .nav-toggle-btn {
  outline: 3px solid var(--accent); outline-offset: 2px;
}

@media (max-width: 767px) {
  .sidebar {
    position: fixed; inset: 0 25% 0 0; width: auto; height: 100vh;
    transform: translateX(-100%); transition: transform 0.2s ease; z-index: 20;
  }
  .nav-toggle-btn {
    display: inline-flex; align-items: center; justify-content: center;
    position: sticky; top: 0; z-index: 15;
    width: 2.75rem; height: 2.75rem; margin: var(--space-2);
    border: 1px solid var(--line); border-radius: 8px;
    background: var(--surface); color: var(--ink); cursor: pointer;
  }
  .nav-toggle-input:checked ~ .shell .sidebar { transform: translateX(0); }
  .nav-toggle-input:checked ~ .shell .nav-scrim {
    display: block; position: fixed; inset: 0; z-index: 19; background: rgb(0 0 0 / 45%);
  }
  .app-main { padding-top: 0; }
}
@media (prefers-reduced-motion: reduce) { .sidebar { transition: none; } }

.date-bar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.date-bar__current { font-weight: 700; font-variant-numeric: tabular-nums; }
.date-picker { position: relative; }
.date-picker__trigger {
  min-width: 17.5rem; min-height: 2.25rem; display: flex; align-items: center;
  justify-content: space-between; gap: var(--space-3); padding: 0.38rem 0.6rem;
  border: 1px solid var(--line); border-radius: 7px; background: var(--surface);
  color: var(--ink); text-decoration: none;
}
.date-picker__trigger:hover { border-color: var(--accent); }
.date-picker__glyph { color: var(--accent); font-size: 0.9rem; }
.date-picker__panel {
  position: absolute; z-index: 9; top: calc(100% + 0.35rem); left: 0;
  display: grid; grid-template-columns: 9.5rem minmax(0, 1fr); width: 40rem;
  overflow: hidden; background: var(--surface); border: 1px solid var(--line);
  border-radius: 9px; box-shadow: 0 0.75rem 2rem rgb(0 47 97 / 18%);
}
.date-picker__presets {
  display: flex; flex-direction: column; padding: var(--space-2);
  border-right: 1px solid var(--line);
}
.date-picker__preset {
  display: block; padding: 0.6rem var(--space-2); border-radius: 5px;
  color: var(--ink); text-decoration: none; font-size: 0.85rem;
}
.date-picker__preset:hover { background: var(--muted-bg); }
.date-picker__preset.is-active { color: var(--navy); background: var(--muted-bg); font-weight: 700; }
.date-picker__calendar-area { min-width: 0; }
.date-picker__titles {
  display: grid; grid-template-columns: 1.7rem 1fr 1fr 1.7rem;
  align-items: center; gap: var(--space-1); padding: var(--space-3) var(--space-2) var(--space-2);
  text-align: center; font-size: 0.85rem;
}
.date-picker__month-arrow {
  display: flex; align-items: center; justify-content: center; width: 1.7rem; height: 1.7rem;
  color: var(--ink); border-radius: 50%; text-decoration: none; font-size: 1.2rem;
}
.date-picker__month-arrow:hover { background: var(--muted-bg); }
.date-picker__error {
  margin: 0 var(--space-3) var(--space-2); color: var(--bad-ink); font-size: 0.85rem;
}
.date-picker__months { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); padding: 0 var(--space-3); }
.date-picker__weekdays, .date-picker__days { display: grid; grid-template-columns: repeat(7, 1fr); }
.date-picker__weekdays span { padding: 0.25rem 0; color: var(--muted); text-align: center; font-size: 0.85rem; }
.date-picker__day {
  min-width: 0; height: 1.7rem; display: flex; align-items: center; justify-content: center;
  color: var(--ink); text-decoration: none; font-size: 0.85rem; font-variant-numeric: tabular-nums;
}
.date-picker__day:hover { background: var(--muted-bg); border-radius: 999px; }
.date-picker__day.is-other-month { color: #9aa8b7; }
.date-picker__day.is-in-range { background: #dceafb; }
.date-picker__day.is-range-start, .date-picker__day.is-range-end {
  background: var(--accent); color: var(--accent-ink);
}
.date-picker__day.is-range-start { border-radius: 999px 0 0 999px; }
.date-picker__day.is-range-end { border-radius: 0 999px 999px 0; }
.date-picker__day.is-range-start.is-range-end { border-radius: 999px; }
.date-picker__day.is-today span { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 2px; }
.date-picker__footer { display: flex; justify-content: flex-end; padding: var(--space-3); border-top: 1px solid var(--line); margin-top: var(--space-3); }
.date-picker__apply, .notice-button {
  display: inline-block; padding: 0.35rem 0.75rem; border-radius: 5px;
  background: var(--accent); color: var(--accent-ink); text-decoration: none; font-weight: 700;
}
.date-picker__apply:hover, .notice-button:hover { background: var(--accent-hover); }
.btn-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.25rem; height: 2.25rem; border: 1px solid var(--line); border-radius: 8px;
  color: var(--ink); text-decoration: none;
}
.pill-row { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
.pill {
  display: inline-block; padding: 0.3rem 0.85rem; border-radius: 999px;
  border: 1px solid var(--line); color: var(--ink); text-decoration: none; font-size: 0.9rem;
}
.pill--active { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.pill--danger { color: var(--bad-ink); border-color: var(--bad-ink); }

.tc-table { table-layout: auto; }
.tc-table .scheduled-cell { background: var(--scheduled-tint); }

/* portal v3.1 directive 9 — the per-column filter row. Zero JavaScript: one GET form wrapping
   the table's card, with the controls in a second <thead> row. A <form> is not permitted content
   of <tr> (browsers hoist it out of the table and orphan every control), so the form wraps the
   CARD and the controls live in ordinary <th> cells. */
.tc-filter-form { margin: 0; }
.tc-filter-row th { padding-top: 0.2rem; padding-bottom: 0.35rem; font-weight: 400; }
.tc-filter-row select, .tc-filter-row input {
  width: 100%; min-width: 0; font: inherit; font-size: 0.9rem; padding: 0.2rem 0.3rem;
  border: 1px solid var(--line); border-radius: 5px; background: var(--bg); color: var(--ink);
}
.tc-filter-row input[type="number"] { width: 7ch; }
.tc-reset { white-space: nowrap; }

/* The mobile half of deviation D8: a SECOND, complete form, shown only under 768px, so the two
   never submit together and can never produce a duplicated query key. */
.tc-filter-card { display: none; }
.tc-filter-card summary { cursor: pointer; font-weight: 700; }
.tc-filter-card select, .tc-filter-card input {
  width: 100%; font: inherit; padding: 0.35rem 0.45rem; border: 1px solid var(--line);
  border-radius: 6px; background: var(--bg); color: var(--ink);
}
.department-pill, .employee-code {
  display: inline-block; border: 1px solid #9eb6cf; border-radius: 999px;
  color: #365d84; background: #f7fafe; white-space: nowrap;
}
.department-pill { padding: 0.08rem 0.38rem; font-size: 0.85rem; }
.department-pill.is-role-mismatch {
  text-decoration: underline;
  text-decoration-color: var(--mismatch-underline);
  text-decoration-thickness: 2px;
  text-underline-offset: 2px;
}
.role-mismatch-note { color: var(--mismatch-underline); }
.meeting-chip {
  display: inline-block; border-radius: 999px; padding: 0.05rem 0.4rem;
  /* 0.85rem, not the brief's 0.78rem: test_portal_shell.py's
     test_css_has_no_retired_rules_and_styles_the_overflow_note pins a 0.85rem floor on every
     explicit font-size in this stylesheet (deviation — see task 5 report). */
  font-size: 0.85rem; white-space: nowrap;
  background: var(--meeting-bg); color: var(--meeting-ink);
  border: 1px solid var(--meeting-ink);
}

/* The GM mapping screen (portal v3 G). No new colour: the page reuses the department pill,
   the muted badge and the existing button. Only layout is new. */
.map-table td { vertical-align: top; }
.map-form { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
            margin: 0; }
.map-form select { font: inherit; padding: 0.3rem 0.4rem; border: 1px solid var(--line);
                   border-radius: 6px; background: var(--bg); color: var(--ink); }
.map-roles h3 { font-size: 1rem; margin: 0 0 var(--space-1); }
.map-checks { display: grid; grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
              gap: var(--space-1) var(--space-3); margin: var(--space-2) 0 var(--space-3); }
.map-check { display: flex; align-items: center; gap: var(--space-2); margin: 0;
             font-weight: 400; }
.employee-name { display: block; font-weight: 600; white-space: nowrap; }
.employee-code { margin-top: 0.12rem; padding: 0.02rem 0.3rem; color: var(--muted); font-size: 0.85rem; }
.nowrap { white-space: nowrap; }
.status-cell { width: 1%; white-space: nowrap; }
.update-cell { width: 22ch; min-width: 22ch; white-space: nowrap; font-variant-numeric: tabular-nums; }
.notice-button { padding: 0.22rem 0.55rem; font-size: 0.86rem; white-space: nowrap; }

.tc-cards { display: none; list-style: none; margin: 0; padding: 0; }
.sort-menu { display: none; }
.row-card { border: 1px solid var(--line); border-radius: 10px; margin-bottom: var(--space-2);
            padding: var(--space-2) var(--space-3); background: var(--surface); }
.row-card > summary { cursor: pointer; list-style: none; display: flex; flex-wrap: wrap;
                      align-items: center; gap: var(--space-2); }
.row-card > summary::-webkit-details-marker { display: none; }
.row-card > summary::after { content: "▾"; margin-left: auto; transition: transform 0.15s ease; }
.row-card[open] > summary::after { transform: rotate(180deg); }
.row-card__name { font-weight: 700; }
.row-card__date { font-size: 0.85rem; }
.row-card__minutes { font-variant-numeric: tabular-nums; }
.row-card dl { display: grid; grid-template-columns: auto 1fr; gap: var(--space-1) var(--space-3);
               margin: var(--space-3) 0 0; }
.row-card dt { color: var(--muted); font-size: 0.85rem; }
.row-card dd { margin: 0; }
.sort-menu__panel { display: flex; flex-direction: column; max-height: 16rem; overflow-y: auto;
                    border: 1px solid var(--line); border-radius: 10px; padding: var(--space-2); }
.sort-menu__item { padding: var(--space-2); color: var(--ink); text-decoration: none;
                   border-radius: 6px; }
.sort-menu__item:hover { background: var(--muted-bg); }
.overflow-note { margin-top: var(--space-2); }
.notice-heading { display: flex; flex-wrap: wrap; align-items: center;
                  justify-content: space-between; gap: var(--space-2); }
.notice-heading h2 { margin-top: 0; }
.notice-card .notice { padding: var(--space-3); }
.notice-facts { display: grid; grid-template-columns: minmax(10rem, auto) 1fr;
                gap: var(--space-1) var(--space-4); }
.notice-facts dt { color: var(--muted); font-weight: 600; }
.notice-facts dd { margin: 0; overflow-wrap: anywhere; }
.notice-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
                  margin-top: var(--space-4); }

/* portal v3 C.6 (Task 11) — the create/edit form and the blocked-refusal page. */
.notice-card { max-width: 40rem; }
textarea {
  width: 100%; font: inherit; padding: 0.45rem 0.55rem; border: 1px solid var(--line);
  border-radius: 6px; background: var(--bg); color: var(--ink); resize: vertical;
}
fieldset { border: 1px solid var(--line); border-radius: 8px; margin: 0.75rem 0 0.25rem;
           padding: var(--space-2) var(--space-3); }
legend { font-weight: 600; padding: 0 var(--space-1); }
.option-row { display: flex; align-items: center; gap: var(--space-2); font-weight: 400;
              margin: 0.35rem 0; }
.option-row input[type="radio"] { margin: 0; }

@media (max-width: 767px) {
  .tc-table { display: none; }
  .tc-cards { display: block; }
  .sort-menu { display: block; margin-bottom: var(--space-3); }
  .tc-table-card.table-scroll { overflow-x: visible; }
  .tc-filter-card { display: block; margin-bottom: var(--space-3); }
}
@media (max-width: 480px) {
  .date-picker__trigger { min-width: min(15.5rem, calc(100vw - 8.5rem)); }
  .date-picker__panel {
    position: fixed; top: 3.5rem; bottom: var(--space-4); left: var(--space-4);
    right: var(--space-4); width: auto; grid-template-columns: 1fr; overflow-y: auto;
  }
  .date-picker__presets { border-right: 0; border-bottom: 1px solid var(--line); }
  .date-picker__titles { position: sticky; top: 0; z-index: 1; background: var(--surface); }
  .date-picker__months { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) { .row-card > summary::after { transition: none; } }

/* portal v3 C.3 — the signature pads. `touch-action: none` is what stops a phone from
   scrolling the page while the associate is signing; without it the pointermove events are
   swallowed by the scroller and the pad records nothing. */
.sign-pad {
  display: block; width: 100%; max-width: 32rem; height: 8rem;
  border: 1px solid var(--line); border-radius: 6px; background: var(--surface);
  touch-action: none; cursor: crosshair;
}
.sign-block { border: 0; padding: 0; margin: var(--space-3) 0; }
.sign-block legend { font-weight: 700; padding: 0; }

/* The cross-department Action marker (spec C.4). Its own selector rather than `.muted`,
   which the stylesheet only ever defines as `p.muted` — a bare `<span class="muted">` would
   inherit nothing and render as ordinary body text, which reads as a broken button. */
/* twice-daily D9 (2026-08-21): `white-space: normal` OVERRIDES the `.nowrap` utility the
   template pairs this class with (`timecards.html:131`, `:224`). It is deliberate, and it is
   the last piece of "no horizontal scroll at 1280px": this cross-department sentence is the
   only cell in the 11-column table that can demand ~160px of unbreakable width, which is
   exactly the case the column arithmetic could not fit. Letting it wrap costs a second line
   on a handful of rows and buys the whole table. Both selectors are specificity (0,1,0) and
   this rule is later in the file, so source order decides -- do not move it above `.nowrap`.
   `.employee-name` keeps its nowrap: names are short and a wrapped name reads as two people. */
.notice-elsewhere { color: var(--muted); font-size: 0.92rem; font-style: italic;
                    white-space: normal; }
