/* The customer portal's stylesheet (T049, T068, T077, T085, T094): neutral, mobile first, 320 px and up, no
   web font.

   Colours are tokens on :root. The three BRAND tokens -- --brand, --accent, --on-brand -- are the ones a
   shop's /theme.css overrides (it is linked after this file and sets only those); everything else is the
   neutral text and surface palette and is never overridden. Two rules from contracts/portal-ui.md hold
   here and must keep holding:

     * --brand is a SURFACE or BORDER colour, never a text colour. Headings and body text use --text.
       Text on a --brand surface uses --on-brand.
     * --accent is the link and focus colour on the page surface, so it must reach 4.5:1 against --surface.

   Contrast, measured against the tokens below (WCAG 2.1 AA wants 4.5:1 for text, 3:1 for UI):
     --text on --surface 16.6    --muted on --surface 7.6     --muted on --bg 7.0
     --on-brand on --brand 8.7   --accent on --surface 6.7    --accent on --bg 6.2
     badge text on its fill 7.0 to 10.2   --field on --surface 5.0 (input and quiet-button borders)  */

:root {
  --text: #1b1f24;
  --muted: #4a5563;
  --bg: #f4f6f9;
  --surface: #ffffff;
  --border: #b8c1cc;        /* decoration only: card and footer rules */
  --field: #66707c;         /* the border of a control: 3:1 or better against its surround (WCAG 1.4.11) */

  /* The neutral brand. A shop's /theme.css replaces these three and nothing else. */
  --brand: #1f4e79;
  --accent: #0b5cad;
  --on-brand: #ffffff;

  --ok-bg: #e3f3e8;
  --ok-text: #0b5d2a;
  --warn-bg: #fff1cc;
  --warn-text: #6b4b00;
  --info-bg: #e4eefc;
  --info-text: #12408c;
  --off-bg: #e8ebef;
  --off-text: #2f363d;
  --bad-bg: #fde7e7;
  --bad-text: #8a1212;

  --radius: 0.5rem;
  --gap: 1rem;
  --focus: 0.1875rem solid var(--accent);
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--text);
  font: 1rem/1.5 system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/* One column, a 16 px gutter at 320 px, never a horizontal scroll. */
.wrap { width: 100%; max-width: 44rem; margin: 0 auto; padding-left: 1rem; padding-right: 1rem; }
.main { flex: 1 0 auto; padding-top: 1.25rem; padding-bottom: 2rem; }
.main:focus { outline: none; }

h1 { margin: 0 0 0.75rem; font-size: 1.5rem; line-height: 1.25; color: var(--text); }
h2 { margin: 0 0 0.75rem; font-size: 1.125rem; line-height: 1.3; color: var(--text); }
h3 { margin: 1.25rem 0 0.5rem; font-size: 1rem; line-height: 1.3; color: var(--text); }
p { margin: 0 0 0.75rem; }
.lead { color: var(--muted); }
.hint { margin-top: 1rem; color: var(--muted); font-size: 0.9375rem; }

a { color: var(--accent); text-underline-offset: 0.15em; }
a:hover { text-decoration-thickness: 0.15em; }

/* Visible focus on everything a keyboard can reach. */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, [tabindex]:focus-visible, progress:focus-visible {
  outline: var(--focus);
  outline-offset: 0.125rem;
}
/* The dialog's title (tabindex="-1", not a tab stop) takes focus when the dialog opens, so a screen reader
   starts at the top. It gets the same ring as everything else through [tabindex]:focus-visible above: a
   keyboard user is shown where focus went, and a mouse user (for whom :focus-visible does not match a
   scripted focus) is not. */

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

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

/* -- header and footer ------------------------------------------------------------------------ */

.site-header { background: var(--surface); border-bottom: 0.25rem solid var(--brand); }
.header-inner {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--gap); padding-top: 0.75rem; padding-bottom: 0.75rem;
}
.brand { display: flex; align-items: center; gap: 0.75rem; min-width: 0; }
.brand-logo { display: block; flex: 0 0 auto; height: 2.25rem; width: auto; max-width: 9rem; object-fit: contain; }
.brand-name { margin: 0; font-weight: 600; overflow-wrap: anywhere; color: var(--text); }
.signout { margin: 0; }

.site-footer { background: var(--surface); border-top: 1px solid var(--border); font-size: 0.9375rem; }
.footer-inner { padding-top: 1rem; padding-bottom: 1rem; }
.footer-inner p { margin: 0 0 0.5rem; overflow-wrap: anywhere; }
.footer-label { color: var(--muted); }
.footer-links, .lang-switch ul { display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; margin: 0 0 0.5rem; padding: 0; list-style: none; }
.lang-switch { margin-top: 0.25rem; }
.lang-switch a[aria-current="true"] { color: var(--text); font-weight: 600; text-decoration: none; }

/* -- cards, forms, buttons -------------------------------------------------------------------- */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
  margin: 0 0 var(--gap);
}

.form .field { margin: 0 0 var(--gap); }
label { display: block; margin: 0 0 0.25rem; font-weight: 600; }
input[type="text"], input[type="password"], input[type="number"], select, textarea {
  display: block; width: 100%; max-width: 100%;
  min-height: 2.75rem;
  padding: 0.5rem 0.75rem;
  font: inherit; color: var(--text);
  background: var(--surface);
  border: 2px solid var(--field);
  border-radius: var(--radius);
}
textarea { min-height: 7rem; resize: vertical; }

.button {
  display: inline-block;
  min-height: 2.75rem;
  padding: 0.5rem 1.25rem;
  font: inherit; font-weight: 600; text-align: center; text-decoration: none; cursor: pointer;
  color: var(--on-brand);
  background: var(--brand);
  border: 2px solid var(--brand);
  border-radius: var(--radius);
}
.button:hover { filter: brightness(1.1); }
.button-quiet { color: var(--text); background: var(--surface); border-color: var(--field); }
/* A control that cannot be used says so by its look as well as by `disabled` (state is never colour alone:
   the label stays, and the reason is printed next to it). Disabled controls are exempt from the contrast
   rules; these colours are legible anyway. */
.button:disabled, .button[disabled] {
  color: var(--off-text); background: var(--off-bg); border-color: var(--field);
  cursor: not-allowed; filter: none;
}
input:disabled, select:disabled, textarea:disabled {
  color: var(--off-text); background: var(--off-bg); cursor: not-allowed;
}

.alert, .banner, .warning, .notice {
  padding: 0.75rem 1rem;
  border-radius: var(--radius);
  border: 1px solid transparent;
  margin: 0 0 var(--gap);
}
.alert { background: var(--bad-bg); color: var(--bad-text); border-color: var(--bad-text); }
.banner { background: var(--info-bg); color: var(--info-text); border-color: var(--info-text); }
.warning, .notice { background: var(--warn-bg); color: var(--warn-text); border-color: var(--warn-text); }

/* -- the status card -------------------------------------------------------------------------- */

.badges { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin: 0 0 0.5rem; }

/* State is the TEXT; the colour only reinforces it (never colour alone). */
.badge, .live {
  display: inline-block;
  padding: 0.125rem 0.625rem;
  border-radius: 999px;
  font-size: 0.9375rem; font-weight: 600;
  border: 1px solid currentColor;
}
.badge-active { background: var(--ok-bg); color: var(--ok-text); }
.badge-scheduled { background: var(--info-bg); color: var(--info-text); }
.badge-paused { background: var(--warn-bg); color: var(--warn-text); }
.badge-finished, .badge-unknown { background: var(--off-bg); color: var(--off-text); }

.live { background: var(--off-bg); color: var(--off-text); }
.live::before { content: ""; display: inline-block; width: 0.5rem; height: 0.5rem; margin-right: 0.4rem; border-radius: 50%; background: currentColor; }
.live-on { background: var(--ok-bg); color: var(--ok-text); }
.live-off::before { background: transparent; border: 2px solid currentColor; }

.note { color: var(--muted); }

.facts { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem 1rem; margin: 0; }
.fact { min-width: 0; }
.fact-wide { grid-column: 1 / -1; }
.fact dt { color: var(--muted); font-size: 0.875rem; }
.fact dd { margin: 0; font-weight: 600; overflow-wrap: anywhere; }
.figure { font-size: 1.5rem; line-height: 1.2; font-variant-numeric: tabular-nums; }

/* -- the controls (T068, T085) ---------------------------------------------------------------- */

/* A message that belongs to a field lives in an element that is always in the page (a live region must
   exist before its text changes), so while it is empty it takes no room. */
.field-error, .status-line, .hint { overflow-wrap: anywhere; }
.field-error:empty, .status-line:empty, .hint:empty { margin: 0; }
.field-error { margin: 0 0 0.5rem; color: var(--bad-text); font-weight: 600; }
.status-line { margin: 0 0 0.5rem; color: var(--muted); }

input[type="range"] { display: block; width: 100%; margin: 0.75rem 0 0.25rem; accent-color: var(--brand); }
input[type="checkbox"], input[type="radio"] {
  flex: 0 0 auto; width: 1.5rem; height: 1.5rem; margin: 0; accent-color: var(--brand);
}
.field-switch { display: flex; align-items: center; gap: 0.75rem; }
.field-switch label, .choice label { margin: 0; }
.choices { display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; }
.choice { display: flex; align-items: center; gap: 0.5rem; }
.choice label { font-weight: 400; }
fieldset { min-width: 0; margin: 0 0 var(--gap); padding: 0; border: 0; }
legend { padding: 0; margin: 0 0 0.25rem; font-weight: 600; }
.actions { margin: 0 0 0.5rem; }

/* The ramp: a native <progress> labelled by the line above it. The fill is a non-text colour, so it may be
   the brand (3:1 against the surface, checked when the operator saved it); no width is ever written inline. */
.ramp { margin-top: var(--gap); }
.ramp label { font-weight: 400; }
progress { display: block; width: 100%; height: 0.875rem; margin: 0.25rem 0 0.75rem; accent-color: var(--brand); }

/* -- the AI Chatters dialog (T094) ---------------------------------------------------------------- */

/* No `display` here: a closed <dialog> must stay display:none. 100% less a gutter keeps it inside 320 px. */
.dialog {
  width: calc(100% - 2rem); max-width: 36rem; max-height: calc(100vh - 2rem);
  padding: 1rem; overflow: auto;
  color: var(--text); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius);
}
.dialog::backdrop { background: rgb(0 0 0 / 0.55); }
.dialog-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--gap); margin: 0 0 var(--gap); }
.dialog-head h2 { margin: 0; }

.token-row { display: flex; gap: 0.5rem; }
.token-row input { flex: 1 1 auto; min-width: 0; }
.tokens { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0 0 0.5rem; padding: 0; list-style: none; }
.token {
  display: inline-flex; align-items: center; gap: 0.25rem; max-width: 100%;
  padding: 0.125rem 0.25rem 0.125rem 0.75rem;
  color: var(--info-text); background: var(--info-bg);
  border: 1px solid var(--info-text); border-radius: 999px;
}
.token span { overflow-wrap: anywhere; }
.token button {
  flex: 0 0 auto; min-width: 2.5rem; min-height: 2.5rem; padding: 0;
  font: inherit; font-weight: 700; color: inherit; background: transparent;
  border: 0; border-radius: 50%; cursor: pointer;
}
.token[aria-invalid="true"] { color: var(--bad-text); background: var(--bad-bg); border-color: var(--bad-text); }

.lines { display: grid; gap: 0.5rem; margin: 0 0 0.75rem; padding: 0; list-style: none; }
.line { padding: 0.5rem 0.75rem; overflow-wrap: anywhere; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); }
.line time { display: block; color: var(--muted); font-size: 0.875rem; font-variant-numeric: tabular-nums; }

@media (min-width: 40rem) {
  .facts { grid-template-columns: repeat(4, 1fr); }
  .fact-wide { grid-column: 1 / -1; }
  h1 { font-size: 1.75rem; }
}

@media (prefers-reduced-motion: reduce) {
  * { scroll-behavior: auto !important; transition: none !important; animation: none !important; }
}
