/* ==========================================================================
   StageCal — shared stylesheet
   Loaded by index.html (calendar), login.html and admin.html (settings).

   START HERE when changing the look: the design tokens below drive every
   page. Change --accent and the buttons, active filters, technician chips,
   logo and focus rings all follow. Page-specific rules stay in each page's
   own <style> block.

   Rules of the house:
   - No CDNs, ever. Fonts and libraries are vendored in /static/vendor/.
     (The app must run on a theatre VPS with no external calls.)
   - Both themes must work. Dark is the default; the theme button cycles
     auto -> light -> dark and writes `sc_theme` to localStorage, which every
     page reads into <html data-theme="...">.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens
   Light is the base. Dark is applied either by system preference (unless the
   user has explicitly chosen light) or by data-theme="dark" on <html>.
   Keep the three blocks below in sync — same variable names, different values.
   -------------------------------------------------------------------------- */
:root {
  --bg: #f5f5f7;              /* page background */
  --panel: #ffffff;           /* cards, header, calendar surface */
  --panel-2: #f5f5f7;         /* recessed areas: chips, descriptions */
  --border: #d2d2d7;
  --text: #1d1d1f;
  --muted: #6e6e73;           /* secondary text */
  --accent: #b45309;          /* brand amber — the one colour to change */
  --accent-text: #ffffff;     /* text ON the accent colour */
  --today: #fdf6e7;           /* today's cell tint */
  --hover: #f0f0f2;
  --warn: #d70015;            /* unstaffed events, errors */
  --warn-soft: rgba(215,0,21,.10);
  --away: #f0b400;            /* someone on leave during the event */
  --away-soft: rgba(240,180,0,.14);
  --ok: #1d9a44;              /* attendee count on events */
  --shadow: rgba(0,0,0,.12);
  --shadow-lg: rgba(0,0,0,.22);
  --stripe: rgba(255,255,255,.28);  /* hatching on unstaffed events */
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #1c1c1e; --panel: #2c2c2e; --panel-2: #3a3a3c; --border: #48484a;
    --text: #f5f5f7; --muted: #98989d; --accent: #ffb020; --accent-text: #2e1f00;
    --today: #3a2f14; --hover: #3a3a3c;
    --warn: #ff453a; --warn-soft: rgba(255,69,58,.16); --ok: #30d158;
    --away: #ffd60a; --away-soft: rgba(255,214,10,.16);
    --shadow: rgba(0,0,0,.4); --shadow-lg: rgba(0,0,0,.6);
    --stripe: rgba(0,0,0,.30);
  }
}
:root[data-theme="dark"] {
  --bg: #1c1c1e; --panel: #2c2c2e; --panel-2: #3a3a3c; --border: #48484a;
  --text: #f5f5f7; --muted: #98989d; --accent: #ffb020; --accent-text: #2e1f00;
  --today: #3a2f14; --hover: #3a3a3c;
  --warn: #ff453a; --warn-soft: rgba(255,69,58,.16); --ok: #30d158;
    --away: #ffd60a; --away-soft: rgba(255,214,10,.16);
  --shadow: rgba(0,0,0,.4); --shadow-lg: rgba(0,0,0,.6);
  --stripe: rgba(0,0,0,.30);
}

/* Tell the browser which scheme is active, so form controls and scrollbars
   render correctly rather than staying stubbornly light. */
html { color-scheme: light; }
@media (prefers-color-scheme: dark) { html:not([data-theme="light"]) { color-scheme: dark; } }
html[data-theme="dark"] { color-scheme: dark; }

/* Stacking order. FullCalendar hardcodes z-index 9999 on its "+N more"
   popover, so anything that must sit above it goes higher. Don't insert new
   layers between these without checking that popover. */
:root {
  --z-tooltip: 10000;
  --z-modal: 10020;
}

/* --------------------------------------------------------------------------
   2. Wordmark font — VENDORED. Never load this from Google Fonts.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "Unbounded";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/static/vendor/unbounded-600.woff2") format("woff2");
}

/* --------------------------------------------------------------------------
   3. Base
   -------------------------------------------------------------------------- */
* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
}

/* --------------------------------------------------------------------------
   4. Logo — the spotlight mark + wordmark. The SVG is inlined in each page's
   markup so it can inherit var(--accent); these rules size and align it.
   -------------------------------------------------------------------------- */
.logo {
  display: flex; align-items: center; gap: 9px;
  text-decoration: none; color: var(--text);
}
.logo-mark { flex: none; display: block; }
.logo-word {
  font-family: "Unbounded", -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 17px; font-weight: 600; letter-spacing: -.2px; line-height: 1;
}
.logo-word span { color: var(--accent); }   /* the "Cal" half */

/* --------------------------------------------------------------------------
   5. Controls — buttons, selects, inputs. Shared by the calendar header and
   the settings page.
   -------------------------------------------------------------------------- */
.btn, select, input[type="search"], input[type="text"], input[type="password"] {
  font: inherit; font-size: 13px; padding: 7px 10px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--panel); color: var(--text); cursor: pointer;
}
input[type="search"], input[type="text"], input[type="password"] { cursor: text; }

.btn:disabled { opacity: .45; cursor: default; }
.btn.active { border-color: var(--accent); color: var(--accent); font-weight: 600; }
.btn.warn.active { border-color: var(--warn); color: var(--warn); }
a.btn { text-decoration: none; display: inline-flex; align-items: center; }

/* Filled, primary action (Save, Open calendar, Download backup) */
.btn-primary {
  background: var(--accent); border-color: var(--accent);
  color: var(--accent-text); font-weight: 600;
}
.btn-primary:hover { filter: brightness(.94); }

select, input { accent-color: var(--accent); }
select:focus, input:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent);
}

/* --------------------------------------------------------------------------
   6. Small shared pieces
   -------------------------------------------------------------------------- */
.spacer { flex: 1; }
.dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }

/* --------------------------------------------------------------------------
   7. Calendar events (month + list). The event DOM is built by index.html's
   eventContent/eventDidMount; these rules style it. Selectors are scoped to
   FullCalendar's classes, so they're inert on login/admin.
   -------------------------------------------------------------------------- */

/* Event typography — a rounded UI face (no CDN; falls back to system-ui on
   the VPS). Slightly smaller than the page default for a calmer grid, with a
   quietest→loudest hierarchy: time, title, unstaffed. */
.ev-inner {
  font-family: ui-rounded, "SF Pro Rounded", "Segoe UI", system-ui, sans-serif;
}
.fc .fc-daygrid-event { font-size: 11px; }          /* was 12 — a touch smaller */
.ev-time {
  font-weight: 400; opacity: .6;
  font-variant-numeric: tabular-nums; letter-spacing: .1px;
}
.fc-daygrid-event .ev-time { font-size: 9px; }      /* smallest, least important */
.ev-title { font-weight: 400; letter-spacing: -.1px; }
/* Attendee count — a bare number in bright green (--ok), so it never reads as
   part of the time sitting next to it. Green = people, muted = time, red =
   problem. (The 👥 icon is gone on purpose: it crowded the grid.) */
.ev-att {
  color: var(--ok); opacity: .95;
  font-weight: 400; font-variant-numeric: tabular-nums; letter-spacing: .1px;
}
.fc-daygrid-event .ev-att { font-size: 9px; }

/* A touch more vertical breathing room between stacked events. Padding (not
   margin) on the harness, so FullCalendar's height measurement includes it
   when it positions the absolutely-placed multi-day bars. */
.fc .fc-daygrid-event-harness { padding-bottom: 2px; }

/* Narrow month cells: the TITLE wins, metadata yields. Without this the
   time/count are flex:none and the title shrinks to a single letter
   ("D 10:00"). Container queries; older browsers just keep the old squeeze.
   The ⚠ is never hidden — smallest glyph, biggest meaning. */
.fc .fc-daygrid-event { container-type: inline-size; }
@container (max-width: 130px) {
  .ev-time { display: none; }   /* the day column already places it; modal has times */
}
@container (max-width: 95px) {
  .ev-att { display: none; }    /* count goes too; tooltip/modal still have it */
}

/* Location colour = a 3px left bar instead of a full wash, so the grid stays
   calm but rooms are still distinguishable. eventDidMount sets --room to the
   room hex and clears the old background wash; the bar only draws once --room
   is present, so nothing changes until that JS edit lands. */
.fc .fc-daygrid-event { position: relative; }
.fc .fc-daygrid-event[style*="--room"] { padding-left: 9px; }
.fc .fc-daygrid-event[style*="--room"]::before {
  content: ""; position: absolute; left: 0; top: 1px; bottom: 1px; width: 3px;
  border-radius: 3px; background: var(--room);
}

/* The signal system (owner's design):
   - red BORDER  = needs attention: no technician, not dismissed, not past.
     It disappears once someone dismisses the event or a technician is added.
   - red ⚠      = zero invitees ("nobody is even planned here"). Purely
     informational, right-aligned with the other metadata, and only shown
     once the border is out of the picture (dismissed/past) — one event
     never carries both signals at once.
   - green COUNT = invitees exist. Green + no border = all is well: either a
     technician is among them or the event was consciously dismissed. */
/* Yellow = someone invited to this event is on leave then. Defined BEFORE
   the red no-tech rule on purpose: when an event is both unstaffed and has
   an absentee, the later red rule wins — staffing beats vacation. */
.fc .fc-event.has-away {
  outline: 2px solid var(--away); outline-offset: -2px; border-radius: 4px;
}
.fc .fc-event.no-tech {
  outline: 2px solid var(--warn); outline-offset: -2px; border-radius: 4px;
  background-image: none;
}
.ev-warn { color: var(--warn); }

/* Absences shown as calendar entries (the 🏖 header toggle): quiet dashed
   bars, clearly not real events. */
.fc .fc-event.abs-event {
  outline: 1px dashed var(--muted); outline-offset: -1px; border-radius: 4px;
  background: transparent;
  color: var(--muted); --fc-event-text-color: var(--muted);
  font-style: italic;
}

/* Finished events recede: this is a planning tool, not an archive (the
   archive is Theatros). Per-event, not per-day-cell, so a multi-day event
   that is still running never gets dimmed for having started yesterday. */
.fc .fc-event.ev-past { opacity: .55; }

/* List rows carry the invitees under the title (comma-separated, techs in
   amber, absentees struck) — on phones the list IS the app, and "which
   technicians" must be readable without tapping.
   flex-wrap is ESSENTIAL: without it the 100%-basis names row crushes the
   shrinkable title to zero width in the nowrap flex line. */
.fc .fc-list-event .ev-inner { flex-wrap: wrap; }
/* like no-tech, the away signal is a soft row wash in the list, not a box */
.fc .fc-list-event.has-away { outline: none; }
.fc-list-event.has-away td { background: var(--away-soft); }
/* absence entries in the list keep their italic muted look, minus the box */
.fc .fc-list-event.abs-event { outline: none; }
/* The toolbar (prev/next/Today/views) pins to the viewport top while the
   page scrolls — in a long list you navigate without scrolling back up.
   Inert in the viewport-filling views (nothing scrolls there). */
.fc .fc-header-toolbar { position: sticky; top: 0; z-index: 4;
  background: var(--panel); padding: 6px 0;
  border-bottom: 1px solid var(--border); }

/* Sticky day headers must be OPAQUE and above the rows — without an explicit
   background + z-index, scrolled row text paints straight through the band.
   They stick BELOW the pinned toolbar: --nav-h is measured by JS. The extra
   .fc-list-sticky class is needed to OUTWEIGH FullCalendar's own
   `.fc .fc-list-sticky .fc-list-day > *` rule, whose top:0 otherwise wins. */
.fc .fc-list-sticky .fc-list-day > th { position: sticky; top: var(--nav-h, 0px); z-index: 3; background: var(--panel); }
.fc .fc-list-day-cushion { background: var(--panel-2); }
/* ...and TODAY's band stands out: amber tint, accent text, accent edge. */
.fc .fc-list-day.fc-day-today .fc-list-day-cushion {
  background: var(--today);
  color: var(--accent);
  box-shadow: inset 3px 0 0 var(--accent);
}
.fc .fc-list-event .ev-names {
  flex: 1 0 100%; display: block; overflow: hidden;
  font-size: 11px; line-height: 1.45; color: var(--muted); margin-top: 2px;
}
.fc .fc-list-event .ev-names span::after { content: ", "; }
.fc .fc-list-event .ev-names span:last-child::after { content: ""; }
.fc .fc-list-event .ev-names .tech { color: var(--accent); font-weight: 600; }
.fc .fc-list-event .ev-names .away { text-decoration: line-through; opacity: .55; }

/* --------------------------------------------------------------------------
   8. Week / day time-grid events
   These blocks are large, so FullCalendar's default solid room colour
   overwhelms the grid (see the old week view). eventDidMount clears that and
   sets --room; the wash is painted HERE from --room — translucent, so
   overlapping events stay readable through each other (the Fantastical
   trick), turning opaque on hover to bring one forward. Theme text colour,
   no heavy border, a solid room-colour left bar, and titles wrap into the
   vertical space a tall block gives.
   -------------------------------------------------------------------------- */
.fc .fc-timegrid-event {
  --fc-event-text-color: var(--text);
  color: var(--text);
  border: none; box-shadow: none; border-radius: 5px;
  /* NO position override here: FullCalendar sizes these blocks by absolute
     positioning, and a `position: relative` collapses every event to its
     text height (a 5h event rendered 1h tall). The ::before bar anchors to
     FC's own absolute positioning just fine. */
  overflow: hidden;
  padding: 3px 5px 3px 8px;
}
.fc .fc-timegrid-event .fc-event-main { padding: 0; }
.fc .fc-timegrid-event[style*="--room"] {
  background: color-mix(in srgb, var(--room) 18%, transparent);
}
.fc .fc-timegrid-event[style*="--room"]:hover {
  background: color-mix(in srgb, var(--room) 30%, var(--panel));
}
.fc .fc-timegrid-event[style*="--room"]::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  border-radius: 3px 0 0 3px; background: var(--room);
}
/* Tall blocks: wrap the title into the vertical space. No count/⚠ here —
   the invitee list below the title already says who's coming (owner's call);
   month and list views keep the compact number/glyph vocabulary. */
.fc .fc-timegrid-event .ev-inner {
  flex-wrap: wrap; align-items: baseline; gap: 0 4px; row-gap: 2px;
}
.fc .fc-timegrid-event .ev-title {
  flex: 1 1 auto; min-width: 0; white-space: normal; line-height: 1.25;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 6;
  overflow: hidden;
}
/* Invitees under the title, technicians in amber (same as the tooltip).
   Comma-separated running text; eventDidMount measures the free space and
   line-clamps to WHOLE lines, so names never get chopped mid-letter.
   Tooltip/modal keep the full list. Remove this block if it feels busy. */
.fc .fc-timegrid-event .ev-names {
  flex: 1 0 100%; display: block; overflow: hidden;
  font-size: 10px; line-height: 1.4; color: var(--muted);
}
.fc .fc-timegrid-event .ev-names span::after { content: ", "; }
.fc .fc-timegrid-event .ev-names span:last-child::after { content: ""; }
.fc .fc-timegrid-event .ev-names .tech { color: var(--accent); font-weight: 600; }
/* On vacation during this event (Theatros absences, opt-in): struck through
   but still readable — the tooltip/modal carry the details. */
.fc .fc-timegrid-event .ev-names .away { text-decoration: line-through; opacity: .55; }
