/* GTM Digital portal shell.
 *
 * Loaded after dashboard.css and deliberately additive: every existing page
 * keeps the panels, tables and badges it already had, and this file supplies
 * only the frame around them - the rail, the top bar, the sign-in page, the
 * home board and billing. New class names throughout (`.rail-*`, `.portal-*`)
 * so nothing here can win or lose a specificity fight with the component
 * styles below it.
 *
 * Two design decisions worth stating, because both were choices and not
 * defaults:
 *
 * 1. The shared shell uses neutral surfaces in both appearances. Green is
 *    reserved for actions and meaningful states; theme.css owns dark tokens.
 *
 * 2. Overview uses equal-sized controls over the mutually exclusive live
 *    counts from `dashboard/portal.py`. Each opens its exact set in Inbox.
 *
 * No web font, matching dashboard.css: the type personality is carried by
 * weight, tracking and tabular numerals instead of by a downloaded face.
 */

/* ---------- portal tokens ---------- */

:root {
  --rail-bg: #ffffff;
  --rail-bg-raised: #f5f5f5;
  --rail-line: #dedede;
  --rail-text: #595959;
  --rail-text-strong: #171717;
  --rail-active: #f0f0f0;

  --section-title-bg: var(--surface);
  --section-title-text: var(--text);
  --section-title-muted: var(--text-muted);
  --section-border: var(--border);

  --rail-w: 15.5rem;
  --rail-w-collapsed: 4.5rem;
  --topbar-h: 3.5rem;
  --tabbar-h: 4rem;
}

/* Numbers are the display face here, so they get their own treatment: equal
   width so a count changing from 9 to 10 does not shift the layout, and tight
   tracking so a large figure reads as one object rather than as digits. */
.figure {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  letter-spacing: -0.03em;
  font-weight: 680;
}

.ico {
  width: 1.25rem;
  height: 1.25rem;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ico-lg { width: 1.5rem; height: 1.5rem; }
.icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---------- the frame ---------- */

body.portal {
  min-height: 100dvh;
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr);
  grid-template-rows: 100dvh;
}

/* The collapsed state is a class on <html> written by the toggle, so the rail
   is already narrow on first paint rather than snapping after hydration.
   Without JavaScript the class never appears and the rail stays expanded,
   which is the state that needs no explanation. */
html.rail-collapsed body.portal { grid-template-columns: var(--rail-w-collapsed) minmax(0, 1fr); }

.rail {
  position: sticky;
  top: 0;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  padding: var(--sp-4) var(--sp-3);
  background: var(--rail-bg);
  border-right: 1px solid var(--rail-line);
  color: var(--rail-text);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.rail a, .rail button { color: inherit; }
.rail-secondary { display: contents; }
.rail-more-head, .rail .rail-more-toggle { display: none; }

/* --- brand --- */

.rail-brand {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2);
  margin-bottom: var(--sp-3);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--rail-text-strong);
}
.rail-brand:hover { color: var(--rail-text-strong); background: var(--rail-active); }
/* The app-icon treatment, and the one place in the portal where something is
   meant to sit *above* the surface rather than on it.
 *
 * The radius is a percentage, not a pixel value, so the mark keeps the same
 * corner proportion at every size it is drawn - 22.4% is the proportion Apple
 * uses for a home-screen icon, which is why a rounded square at that ratio
 * reads as "app" rather than as "picture with rounded corners". `icon.svg`
 * carries the same radius, so the artwork and the clip agree instead of one
 * cutting into the other.
 *
 * The lift is two drop-shadows, not one: a tight, darker contact shadow that
 * pins it to the rail, and a wider, softer one that separates it. `filter:
 * drop-shadow` rather than `box-shadow` because the icon's corners are
 * transparent - a box-shadow would trace the square element box and draw
 * shadow into the corners the rounding just removed. */
.rail-brand img,
.auth-brandside-mark img {
  border-radius: 22.4%;
  filter: drop-shadow(0 1px 1px rgb(0 0 0 / 55%)) drop-shadow(0 4px 10px rgb(0 0 0 / 40%));
}

.rail-brand img { width: 2rem; height: 2rem; flex: none; }
.rail-brand-copy { display: grid; gap: 0.1rem; line-height: 1.1; min-width: 0; }
.rail-brand-copy strong { font-size: var(--text-base); font-weight: 640; letter-spacing: -0.01em; }
.rail-brand-copy span {
  font-size: 0.62rem; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--rail-text); opacity: 0.75;
}

/* --- section labels --- */

.rail-label {
  padding: var(--sp-3) var(--sp-2) var(--sp-1);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--rail-text);
  opacity: 1;
  margin: 0;
}

/* --- navigation items --- */

.rail-item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 0.55rem var(--sp-2);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 540;
  text-decoration: none;
  color: var(--rail-text);
  min-height: 2.4rem;
}
.rail-item:hover { background: var(--rail-active); color: var(--rail-text-strong); }
.rail-item[aria-current="page"] {
  background: var(--rail-active);
  color: var(--rail-text-strong);
  font-weight: 620;
  box-shadow: inset 3px 0 0 0 #83e5ac;
}
.rail-item .ico { opacity: 0.85; }
.rail-item[aria-current="page"] .ico { opacity: 1; }
.rail-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The count rides the item it belongs to. It is the one thing on the rail
   allowed to carry colour, because it is the one thing that means "now". */
.rail-count {
  margin-left: auto;
  min-width: 1.35rem;
  padding: 0 0.35rem;
  height: 1.35rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-pill);
  background: rgb(255 255 255 / 14%);
  color: var(--rail-text-strong);
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
  font-weight: 680;
}
.rail-count-urgent { background: #b3243a; color: #fff; }

/* --- products --- */

.rail-product { align-items: flex-start; padding-block: var(--sp-2); }
.rail-product .ico { margin-top: 0.1rem; }
.rail-product-copy { display: grid; gap: 0.1rem; min-width: 0; }
.rail-product-copy strong { font-weight: 600; font-size: var(--text-sm); }
.rail-product-copy small {
  font-size: 0.7rem; opacity: 0.85; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.rail-product-locked { color: var(--rail-text); cursor: default; }
.rail-product-locked:hover { background: none; color: var(--rail-text); }
.rail-product-locked .ico-lock { margin-left: auto; width: 0.85rem; height: 0.85rem; }

.rail-spacer { flex: 1 1 auto; min-height: var(--sp-4); }
.rail-foot { border-top: 1px solid var(--rail-line); padding-top: var(--sp-3); display: grid; gap: 0.1rem; }

.rail-who { padding: var(--sp-2); display: grid; gap: 0.1rem; line-height: 1.2; min-width: 0; }
.rail-who strong { font-size: var(--text-sm); font-weight: 600; color: var(--rail-text-strong); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail-who span { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 640; }

/* Compact controls and predictable insets throughout the dashboard. */
.portal .panel { min-width: 0; }
.portal .panel > header { gap: var(--sp-3); flex-wrap: wrap; }
.portal .panel h2, .portal .panel button, .portal .panel .button {
  display: inline-flex; align-items: center; gap: var(--sp-2);
}
.portal .panel-body { overflow-wrap: anywhere; }
.portal .panel-body > :first-child { margin-top: 0; }
.portal .panel-body > :last-child { margin-bottom: 0; }
.portal .panel-body form { min-width: 0; }
.portal .panel-body button { max-width: 100%; white-space: normal; }
.portal .panel > h2, .portal .panel > p, .portal .panel > form { margin-inline: var(--sp-4); }
.portal .panel > h2 { margin-block: var(--sp-3); }
.compact-help { margin-top: var(--sp-3); font-size: var(--text-sm); color: var(--text-muted); }
.compact-help summary { cursor: pointer; padding-block: var(--sp-2); }
.compact-help p { max-width: 65ch; margin-block: var(--sp-2); }
.portal .form-panel > header .step-number { background: var(--rail-bg-raised); }
.form-panel-dark { --text: #edf4ef; --text-muted: #b8cbbf; }
.live-indicator { display: inline-flex; align-items: center; gap: 0.4rem; }
.live-indicator::before { content: ""; width: 0.4rem; height: 0.4rem; border-radius: 50%; background: var(--ok); }
.scheduled-clients { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-bottom: var(--sp-4); }
.portal .chip {
  display: inline-flex; align-items: center; min-height: 2.5rem; padding: 0.45rem 0.85rem;
  border: 1px solid var(--section-border); border-radius: var(--radius-pill);
  background: var(--surface); color: var(--text); text-decoration: none;
  font-size: var(--text-sm); font-weight: 600;
}
.portal .chip:hover { background: var(--surface-3); }
.portal .chip-on { background: var(--section-title-bg); color: var(--section-title-text); }
.portal .chip-on:hover { background: #355746; }
.scheduled-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-4); }
.scheduled-queue th[scope="row"] { text-transform: none; letter-spacing: normal; color: var(--text); }
.scheduled-options { display: grid; gap: var(--sp-2); margin-block: var(--sp-4); }
.scheduled-options label { display: flex; align-items: center; gap: var(--sp-2); margin: 0; }
.scheduled-options input { width: 1rem; height: 1rem; margin: 0; flex: none; }
.scheduled-options .badge { margin-left: auto; }
.scheduled-send { display: grid; gap: var(--sp-3); margin-block: var(--sp-4); }
.scheduled-send form { margin: 0; }
.reset-panel { border-color: #cfa9ae; }
.reset-panel > summary { padding: var(--sp-4); cursor: pointer; color: #9e1e30; font-weight: 600; }
.reset-panel > summary .ico { vertical-align: middle; margin-right: var(--sp-2); }
.reset-panel input[type="tel"] { max-width: 22rem; }
.portal .danger-button { border-color: #9e1e30; background: #9e1e30; color: #fff; }
.portal .danger-button:hover { background: #771727; color: #fff; }
@media (max-width: 44rem) { .scheduled-actions { grid-template-columns: minmax(0, 1fr); } }

.rail-signout { width: 100%; }
.rail form { margin: 0; }
.rail button.rail-item {
  background: none;
  border: 0;
  width: 100%;
  cursor: pointer;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 540;
  text-align: left;
}
.rail button.rail-item:hover { background: var(--rail-active); color: var(--rail-text-strong); }

.rail :focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }

/* --- collapsed --- */

html.rail-collapsed .rail { padding-inline: var(--sp-2); align-items: stretch; }
html.rail-collapsed .rail-label,
html.rail-collapsed .rail-who,
html.rail-collapsed .rail-product-locked .ico-lock { display: none; }
/* Keep names in the accessibility tree when the desktop rail shows icons. */
@media (min-width: 40rem) {
  html.rail-collapsed :is(.rail-text, .rail-brand-copy, .rail-product-copy) {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
}
.rail-tooltip {
  position: fixed; z-index: 50; max-width: 15rem; padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text); font-size: var(--text-sm);
  box-shadow: var(--shadow-sm);
}
.rail-tooltip[hidden] { display: none; }
/* The count has nowhere to sit once the label is gone, so it becomes a badge
   pinned to the icon - which is why the item needs to be a positioning
   context here and not in the expanded rail. */
html.rail-collapsed .rail-item {
  position: relative;
  justify-content: center;
  padding-inline: 0;
}
html.rail-collapsed .rail-brand { justify-content: center; padding-inline: 0; }
html.rail-collapsed .rail-count {
  position: absolute;
  top: 0.15rem;
  right: 0.15rem;
  min-width: 1.05rem;
  height: 1.05rem;
  font-size: 0.62rem;
  padding: 0;
}

/* --- main column --- */

.portal-main {
  min-width: 0;
  overflow-y: auto;
  background: var(--bg);
}
body.portal main.dashboard-main,
body.portal .portal-body {
  max-width: 74rem;
  margin: 0 auto;
  padding: var(--sp-5) clamp(var(--sp-4), 3vw, var(--sp-6)) var(--sp-7);
}

.portal-topbar {
  position: sticky;
  top: 0;
  z-index: 15;
  min-height: var(--topbar-h);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) clamp(var(--sp-4), 3vw, var(--sp-6));
  padding-top: max(var(--sp-2), env(safe-area-inset-top, 0px));
  padding-left: max(clamp(var(--sp-4), 3vw, var(--sp-6)), env(safe-area-inset-left, 0px));
  padding-right: max(clamp(var(--sp-4), 3vw, var(--sp-6)), env(safe-area-inset-right, 0px));
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
.portal-crumb {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--text-sm); color: var(--text-muted); margin: 0; min-width: 0;
}
.portal-crumb strong { color: var(--text); font-weight: 620; }
.portal-location { flex: 1 1 auto; min-width: 0; }
.portal-scope { margin: 0 0 var(--sp-1); font-size: var(--text-sm); color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.portal-scope a { color: var(--text); font-weight: 600; text-decoration: none; }
.portal-scope a:hover { text-decoration: underline; }
.portal-crumb .ico { width: 0.9rem; height: 0.9rem; opacity: 0.5; }
.portal-topbar-actions { margin-left: auto; display: flex; align-items: center; gap: var(--sp-2); }

.rail-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.75rem; height: 2.75rem; padding: 0;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  background: none; color: var(--text-muted); cursor: pointer;
}
.rail-toggle:hover { background: var(--surface-2); color: var(--text); border-color: var(--border); }
html.rail-collapsed .rail-toggle .ico-collapse { display: none; }
html:not(.rail-collapsed) .rail-toggle .ico-expand { display: none; }

/* ---------- home: the board ---------- */

.client-filters { display: grid; grid-template-columns: minmax(12rem, 2fr) minmax(9rem, 1fr) auto auto; align-items: end; gap: var(--sp-4); margin-bottom: var(--sp-3); }
.client-filters label { display: grid; gap: var(--sp-2); min-width: 0; font-size: var(--text-sm); }
.client-filters > a { align-self: center; }
@media (max-width: 48rem) {
  .client-filters { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .client-filters label:first-child { grid-column: 1 / -1; }
}

.overview-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-3); margin-bottom: var(--sp-4); }
.overview-stat { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; min-height: 8rem; padding: var(--sp-4); background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius); color: var(--text); text-decoration: none; }
.overview-stat:hover { background: var(--surface-2); color: var(--text); border-color: var(--accent); }
.overview-stat .figure { font-size: 2rem; line-height: 1; }
.overview-stat-label { font-size: var(--text-sm); font-weight: 560; }
.overview-stat-needs-you .figure { color: var(--warn); }
.overview-stat-booked .figure { color: var(--ok); }
@media (max-width: 35rem) {
  .overview-stats { gap: var(--sp-2); }
  .overview-stat { padding: var(--sp-3); min-height: 7rem; }
  .overview-stat .figure { font-size: 1.5rem; }
}

.board-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-4);
}
.board-head h1 { font-size: 1.4rem; letter-spacing: -0.02em; }
.board-head .board-when { color: var(--text-muted); font-size: var(--text-sm); margin: 0; }

/* The signature element. Segments are flex-grown by their share, floored at a
   width that always fits the number, so a one-lead band is still clickable and
   still legible. `flex-basis: 0` is what makes grow behave as a true
   proportion rather than as "share of the leftover space". */
.daybar {
  display: flex;
  gap: 2px;
  margin: 0 0 var(--sp-2);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--border);
  border: 1px solid var(--border);
  min-height: 5.25rem;
}
.daybar-seg {
  /* `--share` is the segment's percentage of the live total, written on the
     element by the template. Growing from a zero basis is what makes the
     widths a true proportion rather than a share of the leftover space; the
     floor below keeps a one-lead band clickable and its number legible. */
  flex-grow: var(--share, 1);
  flex-shrink: 1;
  flex-basis: 0;
  /* Wide enough that the longest label sits on one line without ellipsis. A
     truncated band label ("NEED Y…") is worse than a wider band, because the
     label is the only thing saying what the number counts. */
  min-width: 7.5rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.1rem;
  padding: var(--sp-3) var(--sp-4);
  text-decoration: none;
  background: var(--surface);
  color: var(--text);
  border: 0;
  /* Colour pairs switch together so theme changes never fade through unreadable contrast. */
}
.daybar-seg:hover { color: var(--text); background: var(--surface-2); }
.daybar-seg .figure { font-size: 1.9rem; line-height: 1; }
.daybar-label {
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.daybar-seg-needs-you { background: var(--warn-soft); }
.daybar-seg-needs-you .figure { color: var(--warn); }
.daybar-seg-needs-you .daybar-label { color: var(--warn); }
.daybar-seg-needs-you:hover { background: var(--surface-3); }
.daybar-seg-booked { background: var(--ok-soft); }
.daybar-seg-booked .figure, .daybar-seg-booked .daybar-label { color: var(--ok); }
.daybar-seg-booked:hover { background: var(--surface-3); }
.daybar-seg-talking { background: var(--info-soft); }
.daybar-seg-talking .figure, .daybar-seg-talking .daybar-label { color: var(--info); }
.daybar-seg-talking:hover { background: var(--surface-3); }
.daybar-seg-empty { background: var(--surface); }
.daybar-seg-empty .figure { color: var(--text-muted); font-weight: 600; }

.daybar-urgent {
  display: inline-flex; align-items: center; gap: 0.3rem;
  margin-top: 0.15rem; font-size: 0.7rem; font-weight: 680;
  color: var(--danger);
}
.daybar-urgent .ico { width: 0.8rem; height: 0.8rem; }

.board-foot {
  display: flex; gap: var(--sp-4); flex-wrap: wrap;
  color: var(--text-muted); font-size: var(--text-sm); margin: 0 0 var(--sp-6);
}
.board-foot b { color: var(--text); font-variant-numeric: tabular-nums; font-weight: 640; }

/* The all-clear. An empty board is the good outcome, so it is stated as one
   rather than left as three zeroes the owner has to interpret. */
.board-clear {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-5);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); margin-bottom: var(--sp-6);
}
.board-clear .ico { width: 1.6rem; height: 1.6rem; color: var(--ok); flex: none; }
.board-clear p { margin: 0; }
.board-clear strong { display: block; font-weight: 620; }
.board-clear small { color: var(--text-muted); }

/* ---------- tickets: what is waiting ---------- */

.ticket-list { display: grid; gap: var(--sp-2); margin: 0 0 var(--sp-6); list-style: none; padding: 0; }
.ticket {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--warn);
  border-radius: var(--radius);
  text-decoration: none; color: var(--text);
}
.ticket:hover { background: var(--surface-2); color: var(--text); border-color: var(--border-strong); }
.ticket-urgent { border-left-color: var(--danger); }
.ticket-main { min-width: 0; display: grid; gap: 0.15rem; }
.ticket-main strong { font-weight: 620; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ticket-why { font-size: var(--text-sm); color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ticket-age {
  margin-left: auto; flex: none; font-size: var(--text-sm);
  color: var(--text-muted); font-variant-numeric: tabular-nums;
}
.ticket > .ico-next { flex: none; color: var(--text-muted); width: 1rem; height: 1rem; }

.section-head {
  display: flex; align-items: baseline; gap: var(--sp-3);
  margin: 0 0 var(--sp-3);
}
.section-head h2 {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--text-muted); font-weight: 700;
}
.section-head a { margin-left: auto; font-size: var(--text-sm); text-decoration: none; }
.section-head a:hover { text-decoration: underline; }

/* ---------- billing ---------- */

.bill-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--sp-4);
  padding: var(--sp-5);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); margin-bottom: var(--sp-4);
}
.bill-cell { display: grid; gap: 0.25rem; align-content: start; }
.bill-cell dt {
  font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--text-muted); font-weight: 700;
}
.bill-cell dd { margin: 0; font-size: var(--text-md); font-weight: 620; letter-spacing: -0.01em; }
.bill-state { display: inline-flex; align-items: center; gap: 0.4rem; }
.bill-dot { width: 0.5rem; height: 0.5rem; border-radius: 50%; flex: none; background: var(--text-muted); }
.bill-dot-active { background: var(--ok); }
.bill-dot-due { background: var(--warn); }
.bill-dot-none { background: var(--border-strong); }

.bill-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-bottom: var(--sp-5); }
.bill-actions .ico { width: 1rem; height: 1rem; }
.bill-actions .button, .bill-actions button {
  display: inline-flex; align-items: center; gap: var(--sp-2);
}

.bill-note {
  padding: var(--sp-4);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-muted);
  font-size: var(--text-sm);
  margin-bottom: var(--sp-5);
}
.bill-note strong { color: var(--text); }

/* ---------- sign in ---------- */

/* A split: the brand side carries the same forest as the rail, so signing in
   reads as stepping into the portal rather than as a detached form. It stacks
   to a slim band on a phone - the panel is atmosphere, and atmosphere is the
   first thing a 360px screen should lose. */
body.portal-auth {
  min-height: 100dvh;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  background: var(--surface);
}

.auth-brandside {
  background: var(--rail-bg);
  color: var(--rail-text);
  padding: var(--sp-5) clamp(var(--sp-4), 5vw, var(--sp-7));
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}
.auth-brandside-mark { display: flex; align-items: center; gap: var(--sp-3); color: var(--rail-text-strong); text-decoration: none; }
.auth-brandside-mark img { width: 2.25rem; height: 2.25rem; }
.auth-brandside-mark span { font-size: var(--text-md); font-weight: 640; letter-spacing: -0.01em; }
.auth-brandside h2 {
  color: var(--rail-text-strong);
  font-size: clamp(1.25rem, 3.5vw, 1.75rem);
  letter-spacing: -0.025em;
  font-weight: 600;
  max-width: 22ch;
}
.auth-brandside p { color: var(--rail-text); font-size: var(--text-sm); max-width: 40ch; margin: 0; }
.auth-systems { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-3); }
.auth-systems li { display: flex; align-items: center; gap: var(--sp-3); font-size: var(--text-sm); }
.auth-systems .ico { opacity: 0.8; }
.auth-systems .auth-soon { margin-left: auto; font-size: 0.62rem; letter-spacing: 0.1em; text-transform: uppercase; font-weight: 700; }
/* Written as `.auth-brandside p.auth-brandside-foot`, not as the class alone:
   `.auth-brandside p` above is a class *and* a type selector, so it outranks a
   bare class and would reset this `margin-top` to 0 - leaving the footnote
   sitting under the list instead of pinned to the bottom of the panel. */
.auth-brandside p.auth-brandside-foot {
  margin-top: auto;
  font-size: var(--text-xs);
  opacity: 1;
}

.auth-formside {
  display: grid;
  place-items: center;
  padding: var(--sp-6) clamp(var(--sp-4), 5vw, var(--sp-7));
}
.auth-form { width: min(23rem, 100%); }
.auth-form h1 { font-size: 1.5rem; letter-spacing: -0.02em; margin-bottom: var(--sp-2); }
.auth-form .sub { color: var(--text-muted); font-size: var(--text-sm); margin-bottom: var(--sp-5); }
.auth-form button.primary { width: 100%; padding: var(--sp-3); font-size: var(--text-base); }
.auth-help {
  margin-top: var(--sp-5); padding-top: var(--sp-4);
  border-top: 1px solid var(--border);
  font-size: var(--text-sm); color: var(--text-muted);
}
.auth-help a { text-decoration: none; font-weight: 560; }
.auth-help a:hover { text-decoration: underline; }

@media (min-width: 62rem) {
  body.portal-auth { grid-template-columns: minmax(0, 22rem) minmax(0, 1fr); }
  .auth-brandside { padding-block: var(--sp-7); }
}

/* ---------- phone: the side panel becomes a drawer ---------- */

/* Owner decision, 21 Oct 2026: navigation lives in the side panel at every
   width. On a phone the same panel slides in from the left from the menu
   button in the top bar; without JavaScript the toggle does nothing and the
   destinations remain reachable from each page's own links. */
.rail-toggle .ico-menu { display: none; }
.rail-backdrop { display: none; }
@media (max-width: 39.99rem) {
  body.portal,
  html.rail-collapsed body.portal { grid-template-columns: minmax(0, 1fr); }
  .rail,
  html.rail-collapsed .rail {
    position: fixed; inset: 0 auto 0 0; z-index: 40;
    width: min(18rem, 86vw); height: 100dvh;
    padding: max(var(--sp-3), env(safe-area-inset-top, 0px)) var(--sp-3) max(var(--sp-3), env(safe-area-inset-bottom, 0px));
    transform: translateX(-100%); visibility: hidden;
    transition: transform 180ms ease, visibility 0s linear 180ms;
    box-shadow: 0 0 40px rgb(0 0 0 / 45%);
  }
  html.nav-open .rail { transform: none; visibility: visible; transition: transform 180ms ease; }
  html.nav-open .rail-backdrop { display: block; position: fixed; inset: 0; z-index: 35; background: rgb(0 0 0 / 55%); }
  /* The collapsed preference belongs to wide screens; the drawer is always full. */
  html.rail-collapsed .rail :is(.rail-label, .rail-who) { display: revert; }
  html.rail-collapsed .rail .rail-item { justify-content: flex-start; padding-inline: var(--sp-2); }
  html.rail-collapsed .rail .rail-brand { justify-content: flex-start; padding-inline: var(--sp-2); }
  html.rail-collapsed .rail .rail-count { position: static; }
  .rail-toggle .ico-menu { display: block; }
  .rail-toggle :is(.ico-collapse, .ico-expand) { display: none !important; }
}
@media (max-width: 39.99rem) and (prefers-reduced-motion: reduce) {
  .rail, html.nav-open .rail { transition: none; }
}

@media (pointer: coarse), (max-width: 40rem) {
  :is(.portal, .portal-auth) :is(button:not(.rail-item), .button, .action-button),
  :is(.portal, .portal-auth) input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]),
  :is(.portal, .portal-auth) select { min-height: 2.75rem; }
}

@media (prefers-reduced-motion: reduce) {
  .daybar-seg { transition: none; }
}

/* Shared neutral section headers; borders and spacing establish hierarchy. */
body.portal main.dashboard-main :is(
  .panel > header, .form-panel > header, .section-head, .section-heading,
  .inspector-section-head, .evidence-record > header, .operation-card > header,
  .finding-body > header, details > summary, .subhead,
  .panel > h2, .credential-reveal > h2, .next-steps > h2
) {
  background: var(--section-title-bg);
  color: var(--section-title-text);
  border: 1px solid var(--section-title-bg);
  padding: 0.8rem 1rem;
  border-radius: var(--radius-sm);
  min-width: 0;
  overflow-wrap: anywhere;
}
body.portal main.dashboard-main :is(.panel, .form-panel, .evidence-record, .operation-card) {
  border-color: var(--section-border);
}
body.portal main.dashboard-main :is(.panel > header, .form-panel > header, .evidence-record > header, .operation-card > header) {
  border-radius: calc(var(--radius) - 1px) calc(var(--radius) - 1px) 0 0;
}
body.portal main.dashboard-main :is(
  .panel > header, .form-panel > header, .section-head, .section-heading,
  .inspector-section-head, .evidence-record > header, .operation-card > header,
  .finding-body > header, details > summary
) :is(h2, h3, a, .mono) {
  color: var(--section-title-text);
}
body.portal main.dashboard-main :is(
  .panel > header, .form-panel > header, .section-head, .section-heading,
  .inspector-section-head, .evidence-record > header, .operation-card > header,
  .finding-body > header, details > summary
) :is(p, small, .caption, .eyebrow, .record-id, .optional) {
  color: var(--section-title-muted);
}
body.portal main.dashboard-main :is(.section-heading, .inspector-section-head) h2 {
  margin-top: 0;
  font-size: 1.125rem;
  line-height: 1.3;
}
body.portal main.dashboard-main :is(.section-heading, .inspector-section-head) .eyebrow { display: none; }
body.portal main.dashboard-main :is(.section-heading, .inspector-section-head, .section-head) {
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
}
body.portal main.dashboard-main :is(.evidence-record, .operation-card) > header .button,
body.portal main.dashboard-main .inspector-section-head .chip {
  background: var(--surface-2);
  border-color: var(--border-strong);
  color: var(--section-title-text);
}
body.portal main.dashboard-main .inspector-section-head .chip-on { background: var(--accent-soft); color: var(--accent); }
body.portal main.dashboard-main details > summary::after { color: var(--section-title-muted); }
body.portal main.dashboard-main details > summary:hover { background: var(--surface-2); }
body.portal main.dashboard-main .reset-panel > summary { background: #613039; border-color: #613039; }

/* The action board is deliberately NOT given the title band. It is a live
   status callout, not a section header: it already stands out through its own
   tinted surface and edge, and those carry meaning - pink for "somebody is
   waiting", green for "all clear". Dropping a forest band into the middle of
   the urgent variant put a calm colour on top of the one panel whose whole job
   is to look alarming, and muted the only signal that matters on that page. */
body.portal main.dashboard-main .action-board h2 {
  font-size: 1.15rem;
  letter-spacing: -0.01em;
}

/* Printing a board is printing a to-do list: the chrome is noise. */
@media print {
  .rail, .portal-topbar { display: none; }
  body.portal { display: block; }
}
