@import url('https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400;500;600;700&family=Instrument+Serif&display=swap');

/* BigBite Kjølevakt — the app's one design system.
 *
 * Order of business, top to bottom:
 *   1. tokens        colours, radii, shadows, type
 *   2. base          resets, focus, layout primitives, utilities
 *   3. chrome        app header, notices, toasts
 *   4. controls      buttons, segmented pickers, forms
 *   5. components    cards, pills, tables, charts
 *   6. pages         status hero + meter, device stats, alerts, journal, login
 *   7. print         the journal is the inspection artifact
 *
 * The semantic tokens map onto the --brand-* variables config.js writes at
 * boot, so rebranding is still a one-file change (config.js). The literal
 * after each var() is the fallback used before config.js runs; it MIRRORS
 * config.js so there is no flash of the wrong palette on load.
 *
 * demo/demo.css holds everything only the demo uses. Nothing in here should
 * exist for one page alone unless that page is the only one that can own it.
 *
 * No Tailwind, no build step. The JS renders DOM using these classes. */

/* ======================================================================
   1. tokens
   ====================================================================== */
:root {
  --background: var(--brand-bg, #f4eeea);
  --foreground: var(--brand-text, #241d1a);
  --card: var(--brand-surface, #ffffff);
  --muted: color-mix(in srgb, var(--foreground) 5%, var(--card));
  --muted-foreground: var(--brand-text-muted, #6f625c);
  --border: var(--brand-border, #e3d9d3);
  --primary: var(--brand-primary, #70000a);
  --primary-hover: var(--brand-primary-hover, #8a0010);
  --primary-foreground: var(--brand-on-primary, #ffffff);
  /* On the light ground the maroon reads as text too, so links and the
     focus ring use it directly. */
  --link: var(--brand-link, #70000a);
  --ring: var(--link);

  /* Status palette. Colour means STATUS here and nothing else. The ramps
     derive from the three brand accents rather than carrying their own hex,
     so green/amber/red stay in the BigBite family: -50 is a tint for pill and
     row backgrounds, -200 the matching hairline, and -700 (the text step) IS
     the accent, which already clears 4.5:1 on white. */
  --ok: var(--brand-success, #2c622c);
  --ok-50: color-mix(in srgb, var(--ok) 10%, var(--card));
  --ok-200: color-mix(in srgb, var(--ok) 32%, var(--card));
  --ok-700: var(--ok);

  --warn: var(--brand-warning, #9a5606);
  --warn-50: color-mix(in srgb, var(--warn) 10%, var(--card));
  --warn-200: color-mix(in srgb, var(--warn) 32%, var(--card));
  --warn-700: var(--warn);

  --alert: var(--brand-danger, #a11020);
  --alert-50: color-mix(in srgb, var(--alert) 10%, var(--card));
  --alert-200: color-mix(in srgb, var(--alert) 30%, var(--card));
  --alert-700: var(--alert);

  --brand-mark-from: var(--primary);
  --brand-mark-to: var(--primary-hover);

  /* One radius scale. Controls take -sm, cards the default, the big panels
     (hero, meter) -lg. Nothing else is rounded by hand. */
  --radius-sm: 8px;
  --radius: 12px;
  --radius-lg: 16px;
  /* Elevation is quiet: a warm, low-alpha shadow, never a grey one. */
  --shadow-sm: 0 1px 2px rgba(36,29,26,.06);
  --shadow: 0 1px 3px rgba(36,29,26,.08), 0 6px 18px rgba(36,29,26,.06);
  --shadow-lg: 0 12px 32px rgba(36,29,26,.10);

  /* The measurement is the product, so the numbers get the display face. */
  --font-serif: 'Instrument Serif', Georgia, 'Times New Roman', serif;

  font-family: 'Instrument Sans', ui-sans-serif, -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  color: var(--foreground);
  background: var(--background);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* ======================================================================
   2. base
   ====================================================================== */
* { box-sizing: border-box; }
body { margin: 0; min-height: 100vh; background: var(--background); color: var(--foreground); }
a { color: inherit; text-decoration: none; }
/* native hidden must win even over display:grid/flex component classes */
[hidden] { display: none !important; }
/* one visible keyboard-focus style for every interactive control */
:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; border-radius: 6px; }
/* visually hidden but announced — table captions for screen readers */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ----- layout primitives ----- */
.wrap { margin: 0 auto; max-width: 72rem; padding: 2.5rem 1.5rem; }
.section { margin-bottom: 2rem; }
.row { display: flex; align-items: center; gap: .5rem; }
.between { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.grid { display: grid; gap: .75rem; }
.grid-2 { grid-template-columns: 1fr; }
@media (min-width: 720px) { .grid-2 { grid-template-columns: repeat(2, 1fr); } }
.flex1 { flex: 1; min-width: 0; }
.flexwrap { flex-wrap: wrap; }
.gap-xs { gap: .3rem; } .gap-sm { gap: .5rem; } .gap-md { gap: .75rem; } .gap-lg { gap: 1.5rem; }
.mt-xs { margin-top: .15rem; } .mt-sm { margin-top: .4rem; } .mt-md { margin-top: 1rem; } .mt-lg { margin-top: 1.5rem; }
.mb-md { margin-bottom: 1rem; }
.txt-r { text-align: right; }

/* ----- type ----- */
.h1 { margin: .5rem 0 0; font-family: var(--font-serif); font-size: clamp(1.9rem, 4.4vw, 2.6rem); font-weight: 400; letter-spacing: -.01em; line-height: 1.06; }
.lead { margin: .75rem 0 0; max-width: 42rem; font-size: .9375rem; color: var(--muted-foreground); }
.eyebrow { display: inline-flex; align-items: center; gap: .4rem; font-size: .72rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--muted-foreground); }
.section-title { font-size: .875rem; font-weight: 600; }
.muted { color: var(--muted-foreground); }
.tabular { font-variant-numeric: tabular-nums; }
.t-2xs { font-size: .65rem; } .t-xs { font-size: .72rem; } .t-sm { font-size: .8rem; } .t-md { font-size: .85rem; }
.fw-500 { font-weight: 500; } .fw-600 { font-weight: 600; } .fw-700 { font-weight: 700; }
/* status text colours — the only three colours text is ever tinted with */
.txt-ok { color: var(--ok-700); } .txt-warn { color: var(--warn-700); } .txt-alert { color: var(--alert-700); }
/* small uppercase key, used wherever a value needs a name above it */
.detail-k { font-size: .65rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--muted-foreground); }
.stat-label { font-size: .65rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted-foreground); }
.stat-val { margin-top: .15rem; font-size: 1.4rem; font-weight: 600; }

/* ----- icons ----- */
.ic { display: inline-flex; flex: none; }

/* ======================================================================
   3. chrome
   ====================================================================== */
.app-header {
  position: sticky; top: 0; z-index: 20;
  border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--background) 85%, transparent);
  backdrop-filter: saturate(180%) blur(8px);
}
.app-header .inner { margin: 0 auto; max-width: 72rem; display: flex; align-items: center; justify-content: space-between; gap: .5rem 1rem; padding: .75rem 1.5rem; flex-wrap: wrap; }
.app-header nav { flex-wrap: wrap; gap: .25rem 1rem; }
/* On a phone the brand and the account controls share the first row and the
   nav takes a full row of its own — three stacked rows was most of the screen. */
@media (max-width: 640px) {
  .app-header .inner { padding: .6rem 1rem; }
  .app-header nav { order: 3; width: 100%; }
}
.brand { display: flex; align-items: center; gap: .6rem; font-weight: 700; letter-spacing: -.02em; font-size: 1.05rem; }
.brand .portal-tag { font-size: .68rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--muted-foreground); }
.brand-mark { display: inline-flex; align-items: center; gap: .5rem; }
.brand-mark .dot { width: 1.5rem; height: 1.5rem; border-radius: 7px; background: linear-gradient(135deg, var(--brand-mark-from), var(--brand-mark-to)); }
.tenant-name { max-width: 12rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* A link that reads as an action. Also used on a <button> (Logg ut), so the
   native button chrome is reset here rather than showing through. */
.nav-link {
  position: relative; display: inline-flex; align-items: center; gap: .3rem;
  padding: 0; border: 0; background: none; font: inherit; font-size: .85rem; font-weight: 500;
  color: var(--link); cursor: pointer;
}
.nav-link:hover { text-decoration: underline; }
.nav-link.active { color: var(--foreground); font-weight: 600; }
.nav-link.active::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -.35rem;
  height: 2px; border-radius: 2px; background: var(--link);
}
.back-link { margin-bottom: 1rem; }
/* Count of open avvik, next to "Avvik". Alert tones only, and hidden entirely
   at zero rather than rendered as a calm "0". */
.nav-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.15rem; padding: 0 .3rem; border-radius: 999px;
  font-size: .68rem; font-weight: 600;
  background: var(--alert-50); color: var(--alert-700);
  box-shadow: inset 0 0 0 1px var(--alert-200);
}

.notice { display: flex; align-items: center; gap: .5rem; margin-bottom: 1rem; padding: .6rem .9rem; border: 1px solid var(--warn-200); background: var(--warn-50); color: var(--warn-700); border-radius: var(--radius-sm); font-size: .85rem; }
.loading { padding: 2rem; text-align: center; color: var(--muted-foreground); font-size: .85rem; }
.empty-state { text-align: center; padding: 3rem 1.5rem; color: var(--muted-foreground); }

.toast-host {
  position: fixed; bottom: 1.5rem; right: 1.5rem; display: flex; flex-direction: column;
  gap: .5rem; z-index: 100; pointer-events: none;
}
.toast {
  background: var(--foreground); color: var(--card); padding: .75rem 1rem; border-radius: var(--radius-sm);
  font-size: .875rem; box-shadow: var(--shadow-lg); pointer-events: auto; max-width: 360px;
}
.toast-error { background: var(--alert); }

/* ======================================================================
   4. controls
   ====================================================================== */
.btn {
  display: inline-flex; align-items: center; gap: .4rem; min-height: 40px;
  border-radius: var(--radius-sm); padding: .5rem .9rem;
  font: inherit; font-size: .85rem; font-weight: 500; cursor: pointer;
  border: 1px solid var(--border); background: var(--card); color: var(--foreground);
}
.btn:hover { background: var(--muted); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn:active { transform: translateY(1px); }
@media (prefers-reduced-motion: reduce) { .btn:active { transform: none; } }
.btn-block { width: 100%; justify-content: center; }
.btn-primary {
  background: linear-gradient(180deg, var(--primary-hover), var(--primary));
  color: var(--primary-foreground); border-color: var(--primary);
  box-shadow: 0 2px 8px color-mix(in srgb, var(--primary) 35%, transparent);
}
.btn-primary:hover:not(:disabled) {
  background: linear-gradient(180deg, var(--primary), var(--primary-hover));
  border-color: var(--primary-hover);
  box-shadow: 0 4px 14px color-mix(in srgb, var(--primary) 45%, transparent);
}

/* segmented picker (time ranges) */
.seg { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.seg-btn { border: 0; border-left: 1px solid var(--border); min-height: 40px; background: transparent; color: var(--muted-foreground); padding: .5rem .9rem; font: inherit; font-size: .82rem; cursor: pointer; }
.seg-btn:first-child { border-left: 0; }
.seg-btn.active { background: color-mix(in srgb, var(--foreground) 14%, transparent); color: var(--foreground); font-weight: 600; }

/* ----- forms ----- */
.field { display: flex; flex-direction: column; gap: .375rem; margin-bottom: 1rem; }
.field > label { font-size: .875rem; font-weight: 500; color: var(--foreground); }
/* One input style, whether the page reached it through .field or .fld-input. */
.field > input, .field > select, .field > textarea, .fld-input, .date-input {
  width: 100%; padding: .55rem .7rem; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--card); font: inherit; font-size: .9rem; color: var(--foreground);
  transition: border-color 120ms, box-shadow 120ms;
}
.field > input:focus, .field > select:focus, .field > textarea:focus, .fld-input:focus, .date-input:focus {
  outline: none; border-color: var(--ring);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 25%, transparent);
}
.date-input { width: auto; min-height: 40px; font-size: .82rem; }
.fld-input[aria-invalid="true"] { border-color: var(--alert); }
/* reserved height so validation text never reflows the form */
.ferr { min-height: 1rem; font-size: .7rem; color: var(--alert); }
.form-error {
  background: var(--alert-50); color: var(--alert);
  padding: .625rem .875rem; border-radius: var(--radius-sm); font-size: .875rem; margin-bottom: 1rem;
}
/* a label stacked tightly over its control, for filter rows */
.inline-field { flex-direction: column; margin-bottom: 0; }
.inline-field > label { font-size: .7rem; letter-spacing: .04em; text-transform: uppercase; color: var(--muted-foreground); }

/* ======================================================================
   5. components
   ====================================================================== */
.card { border: 1px solid var(--border); background: var(--card); border-radius: var(--radius); }
.card-body { padding: 1.25rem 1.5rem; }
.card-head { padding: .75rem 1.25rem; border-bottom: 1px solid var(--border); }
/* a card that is itself the link */
.panel-link { display: block; cursor: pointer; transition: border-color 120ms, box-shadow 120ms; }
.panel-link:hover { border-color: color-mix(in srgb, var(--foreground) 20%, var(--border)); box-shadow: var(--shadow-sm); }

.pill { display: inline-flex; align-items: center; gap: .25rem; border-radius: 999px; padding: .12rem .5rem; font-size: .72rem; font-weight: 500; }
.pill-alert { background: var(--alert-50); color: var(--alert-700); box-shadow: inset 0 0 0 1px var(--alert-200); }
.pill-warn { background: var(--warn-50); color: var(--warn-700); box-shadow: inset 0 0 0 1px var(--warn-200); }
.pill-ok { background: var(--ok-50); color: var(--ok-700); box-shadow: inset 0 0 0 1px var(--ok-200); }
.pill-muted { background: var(--muted); color: var(--muted-foreground); }

/* status dots — the hero's and the demo's */
.dot-ok { background: var(--ok); } .dot-warn { background: var(--warn); } .dot-alert { background: var(--alert); } .dot-muted { background: var(--muted-foreground); }

.list { list-style: none; margin: 0; padding: 0; }
.list > li + li { border-top: 1px solid var(--border); }

/* ----- tables ----- */
.table-scroll { overflow-x: auto; }
.hist-card { overflow: hidden; }
.hist-table { width: 100%; min-width: 34rem; font-size: .85rem; border-collapse: collapse; }
.hist-table thead { background: color-mix(in srgb, var(--muted) 50%, transparent); font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; color: var(--muted-foreground); }
.hist-table td { padding: .6rem 1rem; border-top: 1px solid var(--border); }
/* Plain (non-sortable) headers. Scoped with :not(.sort-th) on purpose: a bare
   `.hist-table th` rule out-specifies `.sort-th` and puts back the padding
   that .sort-btn owns, knocking every sortable header out of alignment. */
.hist-table th:not(.sort-th) { padding: .6rem 1rem; font-weight: 500; text-align: left; }
.sort-th { padding: 0; font-weight: 500; text-align: left; }
.sort-btn { display: inline-flex; align-items: center; gap: .3rem; width: 100%; min-height: 40px; padding: .6rem 1rem; background: none; border: 0; font: inherit; font-weight: 500; color: inherit; cursor: pointer; }
.sort-btn.end { justify-content: flex-end; }
.sort-arrow { opacity: .4; }
[aria-sort="ascending"] .sort-arrow, [aria-sort="descending"] .sort-arrow { opacity: 1; }
.more-row { padding: .5rem 1rem; border-top: 1px solid var(--border); font-size: .72rem; background: color-mix(in srgb, var(--muted) 30%, transparent); }

/* key/value facts under an alert: årsak, tiltak, kvittert av */
.resolution { display: grid; grid-template-columns: max-content 1fr; gap: .15rem .75rem; margin: .6rem 0 0; font-size: .8rem; }
.resolution dt { color: var(--muted-foreground); }
.resolution dd { margin: 0; }

/* ----- charts ----- */
.chart { width: 100%; height: 160px; display: block; }
/* secondary metrics sit shorter than the compliance chart, on purpose */
.chart-sm { height: 120px; }
.chart-wrap { position: relative; }
.chart-tip { position: absolute; z-index: 5; display: none; pointer-events: none; transform: translate(-50%, calc(-100% - 12px)); background: var(--foreground); color: var(--background); border-radius: var(--radius-sm); padding: .4rem .55rem; box-shadow: var(--shadow); white-space: nowrap; }
.chart-tip .tip-temp { font-size: .85rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.chart-tip .tip-temp.tone-alert { color: var(--alert-200); }
.chart-tip .tip-temp.tone-warn { color: var(--warn-200); }
.chart-tip .tip-time { margin-top: .1rem; font-size: .68rem; opacity: .8; }
/* compact trend line — no axes, scales to its box */
.spark { display: block; width: 100%; height: 100%; color: var(--foreground); }

/* ======================================================================
   6. pages
   ====================================================================== */

/* ----- status: the verdict ----- */
/* The verdict is a headline on a hairline, not a tinted box: the colour of
   the words and the dot carry the status, and nothing competes with it. */
.hero { display: flex; align-items: flex-end; justify-content: space-between; gap: 1.25rem 2.5rem; flex-wrap: wrap; margin-bottom: 2rem; padding-bottom: 1.75rem; border-bottom: 1px solid var(--border); }
.hero-main { min-width: 0; flex: 1; }
.hero-headline { display: flex; align-items: center; gap: .65rem; margin-top: .5rem; font-family: var(--font-serif); font-size: clamp(1.8rem, 4vw, 2.4rem); font-weight: 400; letter-spacing: -.01em; line-height: 1.08; }
.hero-ok .hero-headline { color: var(--ok-700); } .hero-warn .hero-headline { color: var(--warn-700); } .hero-alert .hero-headline { color: var(--alert-700); }
.hero-dot { width: .8rem; height: .8rem; border-radius: 999px; flex: none; box-shadow: 0 0 0 4px color-mix(in srgb, currentColor 16%, transparent); }
.hero-detail { margin-top: .45rem; font-size: .95rem; color: var(--muted-foreground); }
.hero-action { flex: none; }
/* The verdict answers "er alt i orden nå?". These answer "og kan jeg
   dokumentere det?", so they sit beside it — divided by the same hairline the
   rest of the app uses, and collapsing under it on a phone. */
.hero-facts { flex: none; display: flex; align-items: flex-start; gap: 2.5rem; }
.hero-facts .fact-v { margin-top: .15rem; font-family: var(--font-serif); font-size: 2rem; line-height: 1; }
.hero-facts .fact-sub { margin-top: .2rem; font-size: .72rem; color: var(--muted-foreground); }
@media (max-width: 860px) {
  .hero-facts { width: 100%; padding-top: 1rem; border-top: 1px solid var(--border); }
}

/* ----- status: the meter panel ----------------------------------------
   One appliance, one number. Everything in here is sized to be read in
   passing, across a kitchen — which is why the reading is display-face and
   enormous and the chrome around it is not. Kind (fridge vs freezer) is
   carried by the icon, the name and the band. NEVER by colour. */
.meter-grid { display: grid; gap: 1.25rem; grid-template-columns: 1fr; }
@media (min-width: 900px) { .meter-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.meter {
  border: 1px solid var(--border); background: var(--card);
  border-radius: var(--radius-lg); padding: 1.35rem 1.5rem 1.15rem;
}
.meter:hover { border-color: color-mix(in srgb, var(--foreground) 22%, var(--border)); }
/* Status on the hairline only. A tinted card behind an 80px red number is
   a second, weaker way of saying the same thing. */
.meter.is-warn { border-color: color-mix(in srgb, var(--warn) 45%, var(--border)); }
.meter.is-alert { border-color: color-mix(in srgb, var(--alert) 45%, var(--border)); }
.meter-kind { display: flex; align-items: center; justify-content: space-between; gap: .75rem; }
.meter-kind .who { display: flex; align-items: center; gap: .5rem; min-width: 0; }
.meter-kind .kind { font-size: .7rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; }
.meter-read { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-top: .8rem; }
.meter-num { font-family: var(--font-serif); font-size: clamp(3.2rem, 7vw, 5.2rem); line-height: .92; font-variant-numeric: tabular-nums; }
.meter-num.warn { color: var(--warn); } .meter-num.alert { color: var(--alert); }
.meter-bandbox { flex: none; text-align: right; }
.meter-bandbox .v { margin-top: .2rem; font-family: var(--font-serif); font-size: 1.25rem; color: var(--ok); font-variant-numeric: tabular-nums; }
.meter-say { margin: .8rem 0 0; font-size: .9rem; line-height: 1.5; color: var(--muted-foreground); }
.meter-say strong { font-weight: 600; color: var(--foreground); }
.meter-name { font-size: .72rem; color: var(--muted-foreground); font-variant-numeric: tabular-nums; }
.meter-foot {
  display: flex; align-items: center; justify-content: space-between; gap: .75rem; flex-wrap: wrap;
  margin-top: .85rem; padding-top: .8rem; border-top: 1px solid var(--border);
  font-size: .75rem; color: var(--muted-foreground);
}
.meter-foot .n { color: var(--foreground); font-variant-numeric: tabular-nums; }

/* The gauge answers "how far outside", which a colour alone cannot. */
.gauge { margin-top: 1.15rem; }
.gauge-track { position: relative; height: 26px; }
.gauge-rail { position: absolute; left: 0; right: 0; top: 14px; height: 8px; border-radius: 999px; background: color-mix(in srgb, var(--foreground) 12%, var(--card)); }
.gauge-band { position: absolute; top: 14px; height: 8px; border-radius: 999px; background: color-mix(in srgb, var(--ok) 45%, var(--card)); }
.gauge-mark { position: absolute; top: 8px; width: 4px; height: 20px; margin-left: -2px; border-radius: 2px; background: var(--foreground); }
.gauge-mark.warn { background: var(--warn); } .gauge-mark.alert { background: var(--alert); }
.gauge-ends { display: flex; align-items: center; justify-content: space-between; margin-top: .2rem; font-size: .68rem; color: var(--muted-foreground); font-variant-numeric: tabular-nums; }

/* The band strip: the trend line, tall enough to read, with the excursions
   in the window marked on it — so "38 min" also says WHEN. The minutes come
   from deriveAlerts() over the readings the line is drawn from: they are the
   journal's minutes, not a second opinion. */
.strip { margin-top: 1.15rem; }
.strip-head { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem .75rem; flex-wrap: wrap; }
.strip-v { font-size: .85rem; font-weight: 600; margin-left: auto; }
.strip-track {
  position: relative; margin-top: .45rem; height: 56px; overflow: hidden;
  border-radius: var(--radius-sm); background: color-mix(in srgb, var(--foreground) 6%, var(--card));
}
.strip-track .spark { position: absolute; inset: 0; width: 100%; height: 100%; }
.strip-ex { position: absolute; inset: 0; pointer-events: none; }
.strip-block { position: absolute; top: 0; bottom: 0; }
.strip-warn { background: color-mix(in srgb, var(--warn) 34%, transparent); box-shadow: inset 1px 0 0 var(--warn), inset -1px 0 0 var(--warn); }
.strip-alert { background: color-mix(in srgb, var(--alert) 34%, transparent); box-shadow: inset 1px 0 0 var(--alert), inset -1px 0 0 var(--alert); }
.strip-ends {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  margin-top: .25rem; font-size: .68rem; color: var(--muted-foreground);
}

/* One quiet line under the cards, not another box. */
.detailbar { display: flex; align-items: center; flex-wrap: wrap; gap: .75rem 1.75rem; margin-top: .5rem; }
@media (max-width: 700px) { .detailbar { flex-direction: column; align-items: flex-start; } }
.detail-hint { margin: 0; font-size: .85rem; color: var(--muted-foreground); }

/* ----- device: settings ----- */
.settings-form .fields { display: grid; gap: .75rem 1rem; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.settings-form .field { margin-bottom: 0; }
.save-status { font-size: .8rem; color: var(--ok-700); opacity: 0; transition: opacity 160ms; }
.save-status.on { opacity: 1; }
/* a failed save must not look like a slow one — it stays put */
.save-status.bad { color: var(--alert); font-weight: 500; }
@media (prefers-reduced-motion: reduce) { .save-status { transition: none; } }

/* ----- alerts ----- */
.alert-item { padding: 1rem 0; }
.alert-item:first-child { padding-top: 0; }
/* an unhandled excursion gets a red spine so the list scans at a glance */
.alert-item.is-open { border-left: 3px solid var(--alert); padding-left: .9rem; margin-left: -.9rem; }
.ack-form { margin-top: .9rem; padding: 1rem; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--muted); }
.ack-form .fields { display: grid; gap: .75rem 1rem; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.ack-form .field { margin-bottom: .75rem; }
.ack-form textarea { resize: vertical; }

/* ----- journal ----- */
.jrn-alert { padding: .9rem 0; }
/* The journal is a document: a white sheet on the page, and what an inspector
   is handed. Same tokens as the rest of the app, so it already looks like
   the printout. */
.paper {
  background: var(--card); color: var(--foreground);
  border: 1px solid var(--border); border-radius: 6px; padding: 2rem 2.25rem; box-shadow: var(--shadow);
}
@media (max-width: 640px) { .paper { padding: 1.25rem 1rem; } }

/* ----- login: the left half sells the product while it waits ----- */
.login-split { display: grid; grid-template-columns: 1fr; min-height: 100vh; }
@media (min-width: 860px) { .login-split { grid-template-columns: 1fr 1fr; } }
.login-pitch {
  display: flex; flex-direction: column; justify-content: space-between; gap: 2.5rem;
  padding: clamp(2rem, 5vw, 3.25rem);
  /* The one place the brand maroon gets to dominate — and the one dark
     panel left, so it carries its own light text rather than the page's. */
  color: #f7f0ec;
  background: linear-gradient(165deg, #3a0308 0%, #1d0c0d 55%, #150e0e 100%);
}
.login-pitch img { border-radius: 10px; }
.login-pitch h1 { margin: 0; font-family: var(--font-serif); font-size: clamp(2rem, 4.6vw, 3.1rem); font-weight: 400; line-height: 1.06; }
.login-pitch p { margin: 1rem 0 0; max-width: 26em; font-size: .95rem; line-height: 1.6; color: #d5b6b8; }
.login-pitch ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .6rem; }
.login-pitch li { display: flex; align-items: flex-start; gap: .6rem; font-size: .88rem; color: #e8d3d4; }
.login-pitch li .ic { color: #f0b3b8; margin-top: .1rem; }
.login-form-side { display: flex; flex-direction: column; justify-content: center; padding: clamp(2rem, 5vw, 3.25rem); }
.login-form-side .inner { width: 100%; max-width: 24rem; margin: 0 auto; }

/* ======================================================================
   7. print: the journal is the inspection artifact
   ====================================================================== */
@media print {
  .app-header, .no-print, .btn, .toast-host { display: none !important; }
  /* Screen instruments; on paper the journal carries this. */
  .strip, .hero-facts, .nav-badge { display: none !important; }
  /* Pure black on white, and no tinted ground: toner, not a screen. */
  :root {
    --background: #fff; --card: #fff; --foreground: #000; --muted-foreground: #333; --border: #999;
    --ok: #2c622c; --ok-700: #245224; --warn: #9a5606; --warn-700: #7a4405;
    --alert: #a11020; --alert-700: #8f0c18; --link: #70000a;
  }
  .paper { box-shadow: none; border: 0; padding: 0; }
  body { background: #fff; }
  .wrap { max-width: none; padding: 0; }
  .card, .hist-card { border: 1px solid #999; box-shadow: none; break-inside: auto; }
  .table-scroll { overflow: visible; }
  .hist-table { font-size: 10pt; }
  /* repeat the header on every printed page */
  .hist-table thead { display: table-header-group; }
  .hist-table tbody tr { break-inside: avoid; }
  .jrn-alert { break-inside: avoid; }
  /* colour can't carry meaning on a black-and-white printout */
  .pill { border: 1px solid #666; background: none !important; color: #000 !important; box-shadow: none; }
  .print-sub { font-size: 11pt; color: #000; }
  .print-foot { margin-top: 1rem; font-size: 8pt; }
  a[href]::after { content: ''; }
}
