/* =========================================================================
   BEHA — UI v2 (terrakotta + skog, hierarki-disiplin)

   Palette: terrakotta primary action, skog (deep green) for ON-state /
   suksess. All other surfaces neutral so action stands out. Auto-switches
   to dark via prefers-color-scheme.

   Layout philosophy:
   - Mobile: single column, 360px max input width even on phones-in-landscape
   - Desktop ≥720px: 2-col room grid; settings 2-col where it makes sense
   - Boost lives in the topbar nav (inline button, never floats)

   Hierarchy rules:
   - --brand (hytte-trim rust-rød) ONLY on: primary CTAs, active toggle
     state, hero temperature, watchdog-lock indicator.
   - --on (skog) ONLY on: "is enabled" indicators (heater ON, boost active).
   - Everything else: --fg / --fg-soft / --muted.
   ========================================================================= */

:root {
  /* Brand & state. Brand-rød er plukket direkte fra vindu-rammene på hytta
     (Byrkjesetevegen 119) — saturert rust-rød. Skog-grønn for ON-tilstand
     beholdt fra forrige palett. Hierarchy rules above are unchanged. */
  --brand:       #b25542;            /* mildere rust — mellom dempet terrakotta og saturert rust */
  --brand-soft:  rgba(178, 85, 66, 0.10);
  --brand-deep:  #98463a;            /* hover/active */
  --on:          #4a6741;            /* skog — heater ON, success */
  --on-soft:     rgba(74, 103, 65, 0.12);

  /* Neutral surfaces */
  --bg:          #f5f1ea;            /* warm paper */
  --bg-elev:     #fbf9f4;            /* topbar / footer */
  --card-bg:     #fffdfa;
  --bg-inset:    #f5f1ea;            /* inner panels (now/setpoint boxes) */
  --border:      #e0d8c8;
  --border-strong: #c9c0ad;

  /* Text */
  --fg:          #3a3633;            /* warm dark grey, not pure black */
  --fg-soft:     #5a544f;
  /* WCAG AA fix: previous #8a8278 on --bg was 3.4:1, failed 4.5:1 threshold.
     #6e665b gives 5.6:1 — passes AA for body text, well above the 3.0:1
     large-text threshold. Owner-policy: father has age-related contrast
     sensitivity; we never trade legibility for "subtle" greys. */
  --muted:       #6e665b;
  --accent-fg:   #ffffff;            /* text on --brand surface */
  --coral-text:  #c23a3a;            /* levende status-tall i topbaren = dashboardet */
  --frost-text:  #386ea9;            /* frost-tall i status (blå, som frostvakt) */
  --prog:        #6d4fae;            /* program-lilla for grafen (lesbar) */

  /* Status colors (semantic, used sparingly) */
  --warn:        #b86b1a;
  --warn-soft:   rgba(184, 107, 26, 0.10);
  --error:       #b3261e;
  --error-soft:  rgba(179, 38, 30, 0.08);

  /* Layout primitives */
  --radius-sm:   8px;
  --radius:      14px;
  --radius-lg:   20px;
  --shadow-sm:   0 1px 3px rgba(58, 54, 51, 0.06);
  --shadow:      0 4px 14px rgba(58, 54, 51, 0.09);
  --shadow-lg:   0 12px 36px rgba(58, 54, 51, 0.18);

  /* Form max width — applies to all <input>, <select>. Caps username/email
     at a reasonable 360px even on desktop so it doesn't look amateur. */
  --form-max:    360px;

  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text",
               "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 16px;   /* = dashboardets (nettleser-default) → base-tekst «veksler» ikke lenger stil (eier 2026-08-11) */
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Tri-state (2026-08-10): eksplisitt data-theme fra dashboardet gjelder
   ogsa her; ellers folger OS. Speiler dashboard-v2.css. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --brand:       #cf6c58;
    --brand-soft:  rgba(207, 108, 88, 0.16);
    --brand-deep:  #db8470;
    --on:          #6e8c5e;
    --on-soft:     rgba(110, 140, 94, 0.18);

    --bg:          #14110f;
    --bg-elev:     #1c1916;
    --card-bg:     #221e1a;
    --bg-inset:    #1a1714;
    --border:      #2e2925;
    --border-strong: #3d362f;

    --fg:          #f0eee8;
    --fg-soft:     #c4bdb0;
    /* WCAG AA fix in dark: #8d8478 on #1c1916 was 3.5:1, failed AA. #a89f93
       gives 4.8:1 — passes AA. Same legibility-floor policy as light mode. */
    --muted:       #a89f93;
    --accent-fg:   #14110f;
    --coral-text:  #f58a80;
    --frost-text:  #8dbaea;
    --prog:        #bda3ec;

    --warn:        #d68b3c;
    --warn-soft:   rgba(214, 139, 60, 0.16);
    --error:       #e85d52;
    --error-soft:  rgba(232, 93, 82, 0.12);

    --shadow-sm:   0 1px 3px rgba(0,0,0,0.4);
    --shadow:      0 4px 14px rgba(0,0,0,0.45);
    --shadow-lg:   0 18px 48px rgba(0,0,0,0.55);
  }
}
:root[data-theme="dark"] {
    --brand:       #cf6c58;
    --brand-soft:  rgba(207, 108, 88, 0.16);
    --brand-deep:  #db8470;
    --on:          #6e8c5e;
    --on-soft:     rgba(110, 140, 94, 0.18);

    --bg:          #14110f;
    --bg-elev:     #1c1916;
    --card-bg:     #221e1a;
    --bg-inset:    #1a1714;
    --border:      #2e2925;
    --border-strong: #3d362f;

    --fg:          #f0eee8;
    --fg-soft:     #c4bdb0;
    /* WCAG AA fix in dark: #8d8478 on #1c1916 was 3.5:1, failed AA. #a89f93
       gives 4.8:1 — passes AA. Same legibility-floor policy as light mode. */
    --muted:       #a89f93;
    --accent-fg:   #14110f;
    --coral-text:  #f58a80;
    --frost-text:  #8dbaea;
    --prog:        #bda3ec;

    --warn:        #d68b3c;
    --warn-soft:   rgba(214, 139, 60, 0.16);
    --error:       #e85d52;
    --error-soft:  rgba(232, 93, 82, 0.12);

    --shadow-sm:   0 1px 3px rgba(0,0,0,0.4);
    --shadow:      0 4px 14px rgba(0,0,0,0.45);
    --shadow-lg:   0 18px 48px rgba(0,0,0,0.55);
}


* { box-sizing: border-box; }
/* Responsivt sikkerhetsbelte (alle base-sider, alle enheter): bilder/svg
   skalerer ned i stedet for å sprenge kortet, og ubrytbare strenger (TOTP-
   secret, kommandoer) bryter i stedet for å gi horisontal side-scroll. */
img, svg { max-width: 100%; }
code { overflow-wrap: anywhere; word-break: break-word; }

body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--fg);
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  -webkit-tap-highlight-color: transparent;
  /* Forhindrer iOS pull-to-refresh fra å trigge utilsiktet under poll-syklusen
     (vi reloader allerede automatisk via visibilitychange). */
  overscroll-behavior-y: contain;
}

/* Universal touch-action: manipulation. Eliminerer 300ms tap-delay som iOS
   Safari ellers påfører alle interaktive elementer mens den venter på
   double-tap-zoom. Vi cap-er viewport-scale uansett. */
button, [role="button"], a, input[type="button"], input[type="submit"],
.day-btn, .duration-btn, .bulk-room-item, .heater-toggle,
.cabin-photo-toggle, .room-name-btn {
  touch-action: manipulation;
}

/* Respekter "Reduser bevegelse" (iOS Settings → Tilgjengelighet → Bevegelse).
   Skrur AV alle transitions + animasjoner for brukere som har vestibular-
   sensitivitet eller bare ikke vil ha bouncing/scaling. Lokal nivå-1
   resolution: keep visual feedback (color change), kill physical motion. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* =========================================================================
   Top bar — Beha logo + tagline (no text suffix wordmark)
   ========================================================================= */
.topbar {
  /* Outer wrapper spans the full viewport so the sticky background reaches
     the edges. .topbar-inner inside is constrained to the same 880px max-
     width as <main>, so the visible content aligns vertically.
     Opaque background (no glass blur) — backdrop-filter caused a translucent
     bleed-through on lyst tema og lagde scroll-glitches under playwright.
     Mørkt tema får fortsatt et solid kort over innholdet. */
  display: block;
  padding: 0.6rem 0;   /* ~58px høy topbar = dashboardet; horisontal padding på .topbar-inner */
  background: var(--bg-elev);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 30;
}
.topbar-inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  max-width: 820px;   /* = dashboardets .app, så logo/hamburger står samme sted */
  width: 100%;
  margin: 0 auto;
  padding: 0 20px;    /* padding INNI 820-båndet, som dashboardet (logo 160px fra kant) */
  box-sizing: border-box;
}
/* Høyre-gruppe: Dashboard-knapp + hamburger; ankor (position:relative) for det
   flytende meny-kortet, som legger seg høyrejustert rett under hamburgeren. */
.top-actions {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}
/* Dashboard-knapp — pille som matcher dashboardets modus-knapper (erstatter dem
   på base-sidene). Ligger nærmest hamburgeren (eier 2026-08-11). */
.topbar-dash-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 38px;
  padding: 0 14px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--fg);
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.topbar-dash-btn:hover { background: var(--brand-soft); }
.topbar-dash-btn svg { width: 17px; height: 17px; flex: 0 0 auto; }
.brand { margin: 0; font-size: 1.15rem; font-weight: 500; line-height: 1; }
.brand a {
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
  color: inherit;
  text-decoration: none;
}
.brand-logo {
  width: 34px; height: 34px;   /* = dashboardets logo, så den ikke «hopper» ved sidebytte */
  border-radius: 9px;          /* dashboardets logo har avrundede hjørner */
  object-fit: contain;
  display: block;
}
/* Tagline sits to the right of the logo. Italic, muted, smaller than the
   logo — supports the brand without competing with it. */
.brand-tagline {
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--fg-soft);
  letter-spacing: 0.005em;
  font-style: italic;
  line-height: 1.1;
  white-space: nowrap;
  margin-left: 0.35rem;
}
/* On very narrow phones (< 360px) hide the tagline so the topbar stays
   compact with just the logo. */
@media (max-width: 359px) {
  .brand-tagline { display: none; }
}

/* =========================================================================
   Layout — narrow column on phones, wider grid-driven layouts on desktop
   ========================================================================= */
main {
  flex: 1;
  padding: 1.25rem 1rem 4rem;
  max-width: 880px;
  width: 100%;
  margin: 0 auto;
}

/* =========================================================================
   Card — neutral surface, soft shadow only (no border). Single elevation
   technique = cleaner visual hierarchy.
   ========================================================================= */
.card {
  background: var(--card-bg);
  /* Hårfin kant + større radius + myk skygge = matcher dashboardets kort
     (2026-08-10 modernisering av base-sidene). */
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 1.5rem;
  margin-bottom: 1.1rem;
  box-shadow: var(--shadow-sm);
}
.card h2 { margin: 0 0 0.5rem; font-size: 1.25rem; font-weight: 600; letter-spacing: -0.01em; }
.card h3 { margin: 0 0 0.5rem; font-size: 1.05rem; font-weight: 600; }
.card p  { margin: 0.5rem 0; color: var(--fg-soft); }

/* =========================================================================
   Forms — capped width on desktop
   ========================================================================= */
label {
  display: block;
  margin: 1rem 0 0.5rem;
  font-weight: 500;
  color: var(--fg);
  max-width: var(--form-max);
}
input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"] {
  display: block;
  width: 100%;
  max-width: var(--form-max);
  margin-top: 0.35rem;
  padding: 0.85rem 1rem;
  font-size: 1.05rem;
  font-family: inherit;
  background: var(--bg-inset);
  color: var(--fg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
input:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-soft);
}

/* 2FA / one-time-code inputs — large, monospaced, letter-spaced so 6 digits
   read like a code from across the room. Apply to numeric pattern inputs
   with autocomplete=one-time-code. */
input[autocomplete="one-time-code"] {
  font-size: 1.6rem;
  font-weight: 600;
  letter-spacing: 0.4em;
  text-align: center;
  padding-left: 1.5rem;     /* compensate for letter-spacing pushing first digit right */
  font-variant-numeric: tabular-nums;
}

/* =========================================================================
   Buttons — primary (CTA), secondary (neutral), ghost (icon-only)
   Hierarchy: primary stands out, secondary supports, ghost recedes.
   ========================================================================= */
button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  padding: 0.9rem 1.5rem;
  font-size: 1.05rem;
  font-weight: 600;
  font-family: inherit;
  background: var(--brand);
  color: var(--accent-fg);
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background 120ms ease, transform 80ms ease;
  -webkit-tap-highlight-color: transparent;
  min-height: 48px;
}
button:hover { background: var(--brand-deep); }
button:active { transform: scale(0.98); }
button:disabled { opacity: 0.5; cursor: not-allowed; }

/* Form-level primary CTA — full width only inside auth-shell (login, forgot,
   verify-2fa, reset). Settings/dashboard forms keep auto width so tight inline
   "Lagre" buttons stay tight. */
.auth-shell form > button[type="submit"] { width: 100%; max-width: var(--form-max); }

button.secondary {
  background: var(--bg-inset);
  color: var(--fg);
}
button.secondary:hover { background: var(--border); }

button.link {
  background: none;
  color: var(--brand);
  padding: 0;
  font-size: 0.95rem;
  font-weight: 500;
  min-height: 0;
}
button.link:hover { background: none; text-decoration: underline; }

.button-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.9rem 1.5rem;
  background: var(--brand);
  color: var(--accent-fg) !important;
  text-decoration: none;
  border-radius: var(--radius-sm);
  font-weight: 600;
  min-height: 48px;
}

/* =========================================================================
   Status text + helpers
   ========================================================================= */
/* Inline form error — banner-style. Left-rule + soft fill so it's clearly
   distinct from a paragraph of help text. */
.error, .card p.error {
  color: var(--error);
  background: var(--error-soft);
  border-left: 3px solid var(--error);
  margin: 0 0 1rem;
  padding: 0.65rem 0.9rem;
  font-weight: 500;
  border-radius: var(--radius-sm);
  font-size: 0.95rem;
}
.muted { color: var(--muted); }

.icon { display: inline-block; vertical-align: -0.15em; }

/* =========================================================================
   Footer
   ========================================================================= */
footer {
  padding: 1rem 1.25rem 1.25rem;
  text-align: center;
  color: var(--muted);
  border-top: 1px solid var(--border);
  font-size: 0.85rem;
  background: var(--bg-elev);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
}
.attribution {
  font-size: 0.75rem;
  color: var(--muted);
  opacity: 0.85;
}
.attribution a {
  color: var(--muted);
  text-decoration: underline;
  text-decoration-color: var(--border-strong);
  min-height: 0;
}
.attribution a:hover { color: var(--fg-soft); }

/* =========================================================================
   iOS safe-area + tap target floors.
   ========================================================================= */
@supports (padding: max(0px)) {
  body {
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
  }
  .topbar { padding-top: max(0.6rem, env(safe-area-inset-top)); }
  main    { padding-bottom: max(4rem, calc(4rem + env(safe-area-inset-bottom))); }
}

button, input[type="text"], input[type="email"], input[type="password"], input[type="number"], a {
  min-height: 44px;
}
.topbar a, .skip-link, .reveal-btn, .badge, .icon-btn, button.link, .hamburger { min-height: 0; }

/* =========================================================================
   Skip link (a11y)
   ========================================================================= */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  padding: 0.5rem 0.9rem;
  background: var(--brand);
  color: var(--accent-fg);
  text-decoration: none;
  border-radius: 0 0 8px 0;
  z-index: 100;
}
.skip-link:focus { left: 0; }

button:focus-visible,
a:focus-visible,
input:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 6px;
}

/* =========================================================================
   Pre-auth shell (login / forgot / verify-2fa / reset) — minimal topbar,
   centered card on desktop, less hero-y so brand stops competing with form.
   ========================================================================= */
.auth-shell { max-width: 480px; margin: 0 auto; }
.auth-shell .card { padding: 1.75rem 1.5rem; }
.auth-shell .card > h2:first-of-type {
  margin-bottom: 0.4rem;
  font-size: 1.35rem;
}
.auth-shell .muted { font-size: 0.95rem; line-height: 1.45; }

/* Mobil-landscape: 320-393px høyde er kort. Login/2FA/forgot må fit uten
   å scrolle. Reduserer padding + spacing aggressivt så cardet får plass. */
@media (orientation: landscape) and (max-height: 500px) {
  body.auth-page main {
    padding: 0.5rem 1rem;
  }
  .auth-shell .card {
    padding: 0.7rem 1rem;
    margin-top: 0.25rem;
  }
  .auth-shell .card > h2:first-of-type {
    margin: 0 0 0.25rem;
    font-size: 1.05rem;
  }
  .auth-shell .muted { font-size: 0.8rem; line-height: 1.3; }
  .auth-shell form label {
    font-size: 0.85rem;
    margin-bottom: 0.15rem;
  }
  .auth-shell form input {
    padding: 0.5rem 0.7rem;
    margin-bottom: 0.5rem;
  }
  .auth-shell form > button[type="submit"] {
    margin-top: 0.3rem;
    padding: 0.55rem 1rem;
  }
  .forgot-link { margin-top: 0.5rem; font-size: 0.8rem; }
}

.forgot-link { text-align: center; margin: 1.25rem 0 0; font-size: 0.9rem; }
.forgot-link a { color: var(--brand); text-decoration: none; font-weight: 500; }
.forgot-link a:hover { text-decoration: underline; }

/* Password reveal — eye icon button overlaid in input. Larger tap target,
   icon-only so no language dependency. */
.input-with-toggle { position: relative; display: block; max-width: var(--form-max); }
.input-with-toggle input { padding-right: 3rem; }
.reveal-btn {
  position: absolute;
  right: 0.35rem;
  top: 50%;
  transform: translateY(-50%);
  padding: 0;
  width: 40px; height: 40px;
  background: transparent;
  color: var(--muted);
  border: none;
  border-radius: 8px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
}
.reveal-btn:hover { background: var(--brand-soft); color: var(--brand); }
.reveal-btn[aria-pressed="true"] { color: var(--brand); }

/* QR-box on /reset */
.qr-box { display: flex; justify-content: center; padding: 1rem 0; }
.qr-box svg {
  width: 240px; height: auto; max-width: 100%;   /* skalerer ned på 320px uten å forvrenges */
  background: #fff;
  padding: 10px;
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
}

/* =========================================================================
   Dashboard hero — cabin photo with gradient overlay. Compressed on mobile
   so it doesn't push the actionable content below the fold.
   ========================================================================= */
.hero {
  position: relative;
  margin: -1.25rem -1rem 1.5rem;
  overflow: hidden;
  min-height: 200px;
  display: flex;
  align-items: flex-end;
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
@media (min-width: 720px) {
  .hero { min-height: 280px; }
}
/* Mobil-landscape: når brukeren snur telefonen til siden, har vi typisk
   320-430px høyde. Hero-content gjøres inline (én linje) så det tar
   minimal vertikal plass og rom-cards er umiddelbart synlig. Greeting
   dropet i landscape -- ren plass-besparelse, cabin-context er viktigere.
   Påvirker bare ekte mobil-landscape (max-height: 500), ikke tablet/desktop. */
@media (orientation: landscape) and (max-height: 500px) {
  .hero {
    min-height: 0;
    margin-bottom: 0.75rem;
  }
  .hero-text {
    padding: 0.55rem 1rem;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.4rem 0.9rem;
  }
  .hero-text h2 { display: none; }  /* greeting dropet i landscape */
  .cabin-temp {
    font-size: 1rem;
    display: inline-flex;
    align-items: baseline;
    gap: 0.5rem;
  }
  .cabin-temp-label {
    font-size: 0.65rem;
    margin-bottom: 0;
    display: inline;
  }
  .cabin-context {
    font-size: 0.78rem;
    margin: 0;
  }
}
.hero-bg {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 40%;
  z-index: 0;
  transition: filter 600ms ease;
}
/* Døgnsyklus-filter på hero-bildet. JS setter data-period på .hero basert
   på klokkeslett (natt/morgen/dag/kveld) og CSS tinter bildet for å matche.
   Subtilt -- detalj som gjør appen "lever" med tida. */
.hero[data-period="natt"] .hero-bg {
  filter: brightness(0.45) contrast(1.05) hue-rotate(-15deg) saturate(0.85);
}
.hero[data-period="morgen"] .hero-bg {
  filter: brightness(0.95) saturate(1.1) hue-rotate(-5deg);
}
.hero[data-period="dag"] .hero-bg {
  filter: none;
}
.hero[data-period="kveld"] .hero-bg {
  /* Gylden time -- varm orange/red tint */
  filter: brightness(0.85) saturate(1.25) hue-rotate(8deg) sepia(0.15);
}
/* Sommer/vinter-bytte-knapp øverst i hero. Lite ikon (sol når vinter er
   aktiv = "klikk for sommer"; snøflak når sommer er aktiv). */
.cabin-photo-toggle {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  z-index: 3;
  width: 36px; height: 36px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: rgba(0,0,0,0.35);
  color: #fff;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 120ms ease, transform 80ms ease;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  min-height: 36px;
}
.cabin-photo-toggle:hover { background: rgba(0,0,0,0.55); }
.cabin-photo-toggle:active { transform: scale(0.92); }
.cabin-photo-toggle:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(0,0,0,0.78) 0%,
    rgba(0,0,0,0.40) 45%,
    rgba(0,0,0,0.05) 100%);
  z-index: 1;
}
.hero-text {
  position: relative;
  z-index: 2;
  padding: 1.5rem 1.25rem 1.1rem;
  color: #fff;
  width: 100%;
}
.hero-text h2 {
  margin: 0 0 0.25rem;
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  text-shadow: 0 1px 8px rgba(0,0,0,0.5);
}
.cabin-temp {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: rgba(255,255,255,0.97);
  text-shadow: 0 1px 8px rgba(0,0,0,0.5);
}
.cabin-temp .cabin-temp-label {
  display: block;
  /* 0.75rem = 12.75px -- over the 12px legibility floor (Helsedirektoratet
     anbefaling, og praktisk grense i sterk dagslys/Pro Max-skjerm). */
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.85;
  margin-bottom: 0.05rem;
  font-variant-numeric: normal;
}
.cabin-context {
  margin: 0.65rem 0 0;
  font-size: 0.92rem;
  color: rgba(255,255,255,0.95);
  text-shadow: 0 1px 6px rgba(0,0,0,0.6);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.9rem;
}
.cabin-context .ctx-item {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  white-space: nowrap;
}
.cabin-context .ctx-item .icon { color: #fff; opacity: 0.95; }
/* "Neste døgn"-range — secondary info, slightly smaller + lower contrast so
   the current temperature is the primary read. */
.cabin-context .ctx-range {
  font-size: 0.82rem;
  opacity: 0.85;
  font-weight: 400;
  white-space: nowrap;
}
/* On narrow phones, drop the range onto its own line under the current temp
   so the row doesn't truncate. */
@media (max-width: 419px) {
  .cabin-context .ctx-range {
    display: block;
    margin-left: 1.55rem;  /* line up under the icon + space */
    margin-top: 0.05rem;
  }
}

/* =========================================================================
   Banner — info / warn / demo variants. Uses pure surfaces (no brand color
   bleed) so it doesn't compete with action cards.
   ========================================================================= */
/* `hidden`-attributtet skal alltid skjule, uavhengig av display-mode
   som .banner setter under. Bug 2026-05-24: tomme state-banner og
   boost-global-banner viste seg som ovale piller fordi `.banner { display:
   flex }` overstyrer `[hidden]`. */
[hidden] { display: none !important; }

/* Toast-style: compact pill that auto-sizes to content and centers above the
   content it relates to. Replaces the previous full-width banner since the
   user reported "tar hele bredden" — chunky for one-word messages like
   "Lagret." */
.banner {
  display: flex;
  align-items: center;
  width: fit-content;
  max-width: 100%;
  padding: 0.45rem 1rem;
  margin: 0 auto 1.1rem;
  border-radius: 999px;
  background: var(--bg-inset);
  color: var(--fg);
  font-size: 0.9rem;
  font-weight: 500;
  line-height: 1.2;
  border: 1px solid transparent;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
  animation: banner-pop 180ms ease-out;
}
.banner.warn  { background: var(--error-soft); color: var(--error); border-color: color-mix(in oklab, var(--error) 30%, transparent); }
.banner.demo  { background: var(--warn-soft);  color: var(--warn);  border-color: color-mix(in oklab, var(--warn) 30%, transparent); }
.banner.info  { background: var(--on-soft);    color: var(--on);    border-color: color-mix(in oklab, var(--on) 30%, transparent); }
.banner p {
  margin: 0;
  color: inherit;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}
.banner .banner-icon {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
}
.banner .banner-text { line-height: 1.25; }
@keyframes banner-pop {
  from { transform: translateY(-4px); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}

/* =========================================================================
   Rooms grid — single column mobile, 2 wide on tablet/desktop
   ========================================================================= */
.rooms-grid {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}
@media (min-width: 720px) {
  .rooms-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1.25rem;
  }
}

.room-card {
  background: var(--card-bg);
  border-radius: var(--radius);
  padding: 0.95rem 1.1rem 1rem;
  box-shadow: var(--shadow-sm);
  transition: box-shadow 120ms ease;
  /* Container query target -- tall innenfor cardet skalerer med
     CARDETS bredde, ikke viewport. Mye mer robust enn vw-baserte clamps
     siden det funker likt enten cardet sitter i 1-col mobile eller
     2-col desktop eller noensinne 3-col tablet-landscape. iOS Safari 16+. */
  container-type: inline-size;
  container-name: roomcard;
}
.room-card:hover { box-shadow: var(--shadow); }

/* Off-state: alle ovner manuelt skrudd av (eller mixed offline+disabled).
   Dimmer setpoint-blokken siden tallet ikke har umiddelbar effekt — men
   IKKE .now/INNE NÅ siden temp-sensoren fortsatt måler virkeligheten i
   rommet (det er fortsatt 21.7° der inne selv om vi ikke varmer). Bruker
   kan fortsatt justere setpointen som "pre-sett før jeg slår på", så
   .adj-knappene er bare dimmet, ikke disabled. */
.room-card--off .setpoint,
.room-card--off .program-summary { opacity: 0.55; }
.room-card--off .setpoint-val { color: var(--fg-soft); }
.room-card--off .adj { color: var(--fg-soft); border-color: var(--border); }
.room-card--off .adj:hover { background: var(--bg-inset); border-color: var(--border); }

.room-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.65rem;
  gap: 0.75rem;
}
.room-head h3 {
  margin: 0;
  font-size: 1.2rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
  flex: 1 1 auto;
}
.room-name-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
/* Click-to-rename room: the room name is a button styled as text. Subtle
   hover-underline tells the user it's editable; no border so it blends in
   with the heading until you mouse over it. */
.room-name-btn {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  cursor: text;
  text-align: left;
  min-height: 0;
  border-radius: 4px;
}
.room-name-btn:hover .room-name-text,
.room-name-btn:focus-visible .room-name-text {
  text-decoration: underline;
  text-decoration-color: var(--brand);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 4px;
}
.room-name-btn:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
.room-head .badge { flex: 0 0 auto; }
.room-head .lock-indicator {
  color: var(--brand);
  opacity: 0.9;
}

/* Status badge — small text-only chip, no brand fill so it doesn't compete */
.badge {
  font-size: 0.72rem;
  font-weight: 700;
  padding: 0.25rem 0.55rem;
  border-radius: 999px;
  white-space: nowrap;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: var(--bg-inset);
  color: var(--fg-soft);
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}
.badge.boost { background: var(--brand-soft); color: var(--brand); }
.badge.program { background: var(--on-soft); color: var(--on); }
.badge.offline { background: var(--error-soft); color: var(--error); }
/* "Avslått" — alle ovner manuelt av. Mørkere grå enn default-badge så
   det leses tydeligere som "AV" på første blikk. */
.badge.disabled {
  background: var(--bg-inset);
  color: var(--fg-soft);
  border: 1px solid var(--border-strong);
}
/* "Holder temp" = watchdog er på + manuell modus. Vis tydelig at vi
   passer på (mørkere grønn enn .program så lyst-tema får nok kontrast --
   var(--on)-text på var(--on-soft) er for tett-på på lyst tema). */
.badge.hold {
  background: var(--on-soft);
  color: var(--on);
  border: 1px solid color-mix(in oklab, var(--on) 35%, transparent);
}
/* "Beha-program" = vi lar Beha styre (ikke enforce). Subtil warning-tint
   så bruker ser at vi IKKE beskytter mot 6°C-resetten. */
.badge.beha { background: var(--warn-soft); color: var(--warn); }

/* Temps layout (vertikal stack, matcher Beha-app sin pattern):
     [INNE NÅ 21.4°]   ← kompakt, full bredde
     [- 22.0° +]       ← full bredde, knapper i hjørnene, tall i midten
   Tidligere hadde vi 2-kolonners grid med .now venstre + .setpoint høyre.
   Det fungerte ikke fordi .setpoint trenger plass til 2 touch-targets
   PLUSS et matching-size tall, og 50%-kolonne av en 358px room-card
   (~180px) er for smalt på iPhone-portrait.
   PROGRAM/BOOST-modus stacker tilsvarende:
     [INNE NÅ 17.5°]
     [PROGRAM NÅ 21.0°]
   Begge taller har samme størrelse fordi de er "to sider av samme info". */
.temps {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.now, .setpoint {
  background: var(--bg-inset);
  border-radius: 12px;
  padding: 0.7rem 0.9rem;
}
/* .now får inline label+value-layout: "INNE NÅ" til venstre, tall til
   høyre. Sparer vertikal plass, matcher Beha-app sin "INNE NÅ: 18.9°"-
   konvensjon. */
.now {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.8rem;
}
.now .label {
  font-size: 0.75rem;
  color: var(--muted);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 700;
  white-space: nowrap;
  flex-shrink: 0;
}
/* Høyre kolonne i .now: stort tall + liten "målt HH:MM"-linje stablet, høyre-
   justert. Beholder space-between (label venstre) uendret. */
.now-val {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.1rem;
  min-width: 0;
}
/* "målt HH:MM" — diskret undertekst. Stale (> 15 min) farges varmt. */
.measured-age {
  font-size: 0.7rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  line-height: 1;
}
.measured-age--stale {
  color: var(--accent, #e34c4c);
}
/* "oppdaterer" mens en fersk avlesning er på vei (rett etter åpning). Ingen
   puls på teksten -- bare animerte prikker: oppdaterer. -> .. -> ... -> osv.
   Span-teksten er "oppdaterer" (uten prikker); ::after animerer prikkene via
   content. Fast bredde på ::after så "oppdaterer" ikke hopper når prikkene
   vokser. prefers-reduced-motion -> statiske "…". */
.measured-age--refreshing {
  color: var(--muted);
}
.measured-age--refreshing::after {
  content: ".";
  display: inline-block;
  width: 1.1em;
  text-align: left;
  animation: oppdaterer-dots 1.5s infinite;
}
@keyframes oppdaterer-dots {
  0%   { content: "."; }
  33%  { content: ".."; }
  66%  { content: "..."; }
  100% { content: "."; }
}
@media (prefers-reduced-motion: reduce) {
  .measured-age--refreshing::after { content: "…"; width: auto; animation: none; }
}
.big {
  /* Container-query-based sizing: tall skalerer med room-card-bredden,
     ikke viewport. Mye mer pålitelig fordi rom-card kan være 280px (1-col
     iPhone SE) eller 600px (2-col desktop) avhengig av layout, og clamp()
     med vw-units traff feil i begge ekstremer.
       - 280px card (iPhone SE 320px viewport): 17cqw = 47px → cap 2.6rem
       - 358px card (iPhone 14 393px viewport): 17cqw = 60px → cap 2.6rem
       - 600px card (desktop 2-col): cap 2.6rem
     Min 1.8rem sikrer lesbarhet selv om container krymper drastisk. */
  font-size: clamp(1.8rem, 17cqw, 2.6rem);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: 1.05;
  color: var(--fg);
}

/* Setpoint: - VALUE + på én rad, full room-card-bredde (etter at .temps
   er stacket flex-column over). Knappene i hjørnene, tallet i midten med
   flex:1 så det får all mellomrom. */
.setpoint {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.5rem 0.6rem;
}
.adj {
  /* CLAUDE.md spec + 2026-05-25 UX audit: 60px target for father's thumb.
     Previously 52px; failed Apple HIG 44pt + our own spec. */
  width: 60px; height: 60px;
  font-size: 1.7rem;
  font-weight: 600;
  border-radius: 50%;
  border: 1.5px solid var(--border-strong);
  background: var(--card-bg);
  color: var(--brand);
  cursor: pointer;
  flex-shrink: 0;
  min-height: 60px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  box-shadow: var(--shadow-sm);
  /* Eliminates iOS Safari's 300ms tap-delay on this hot button. */
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
  transition: transform 80ms ease, background 100ms ease, border-color 100ms ease;
}
.adj:hover { background: var(--brand-soft); border-color: var(--brand); }
.adj:active { transform: scale(0.92); background: var(--brand); color: var(--accent-fg); }
.adj:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  background: var(--bg-inset);
  border-color: var(--border);
}
.adj:disabled:hover { background: var(--bg-inset); border-color: var(--border); }
/* Setpoint-tallet er INTERAKTIVT (bruker holder fingeren her), ikke et
   glance-tall som INNE NÅ. Mindre font slipper at det får plass mellom de
   to 60px .adj-knappene.
   2026-05-25: tallet er nå en <button> (tap-to-edit). Button-defaults
   (border, padding, background) må nulles så det ser identisk ut til
   .adj-omkringliggende span-stilen før knappifisering. */
.setpoint-val {
  flex: 1;
  text-align: center;
  /* Matcher .big — setpoint er en temperatur akkurat som INNE NÅ. Etter
     stack-layout (over) får .setpoint full room-card-bredde, så det er
     plass til 2 knapper (44-60px) + matching-size tall mellom dem. */
  font-size: clamp(1.8rem, 17cqw, 2.6rem);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: 1.05;
  color: var(--fg);
  min-width: 0;
}
button.setpoint-val {
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  padding: 0.1rem 0.4rem;
  background: transparent;
  cursor: pointer;
  /* iOS Safari sometimes adds a tap-highlight rectangle in brand color;
     vi gjør den usynlig (focus-visible-ringen er bedre signal). */
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  border-radius: 8px;
  transition: background 100ms ease, color 100ms ease;
  /* iOS long-press kunne ellers selecte tekst eller vise context menu
     (copy/define) på "22°". Begge er fiendtlig UX for en tap-til-edit-
     knapp -- forhindres med user-select + touch-callout. */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  /* Diskret visuell affordance: tallet er klikkbart men skal ikke
     skrike om det. Hover viser brand-tint så desktop-brukere ser det;
     mobile bruker ikke hover men får cursor-feedback via tap-highlight. */
}
button.setpoint-val:hover { color: var(--brand); background: var(--brand-soft); }
button.setpoint-val:active { transform: scale(0.97); }
button.setpoint-val:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
/* Inline edit-modus: span/button erstattes av et input som beholder
   eksakt samme font-size og tabular-nums for null layout-shift. iOS
   gir decimal-tastatur via inputmode="decimal" og "Ferdig"-tast via
   enterkeyhint="done". */
input.setpoint-val--editing {
  /* tabular-nums + font-size + line-height kommer fra .setpoint-val */
  background: var(--bg-inset);
  border: 1.5px solid var(--brand);
  border-radius: 10px;
  padding: 0.05rem 0.3rem;
  margin: 0;
  outline: none;
  width: 100%;
  box-sizing: border-box;
  box-shadow: 0 0 0 3px var(--brand-soft);
  /* iOS removes default border-radius on input -- vår tydelige border
     gjenoppretter det visuelle "dette er et input"-cue. */
  -webkit-appearance: none;
  appearance: none;
}

/* .adj-knapper er touch-targets så de skalerer trinnvis, ikke flytende:
     - default 60px (CLAUDE.md spec, far's thumb)
     - 52px på iPhone 14 og lignende (393px viewport)
     - 44px på iPhone SE 1st gen / iPhone 5s (Apple HIG minimum)
   Container query på room-card håndterer setpoint-tall + glance-tall;
   .adj-knappene er fortsatt media-query siden touch-targets ikke skal
   skalere flytende -- enten store nok eller ikke. */
@container roomcard (max-width: 380px) {
  .adj {
    width: 52px;
    height: 52px;
    min-height: 52px;
    font-size: 1.5rem;
  }
}
/* Veldig smale cards (iPhone SE 1st gen ~236px container): mindre .adj
   så stepper-raden får plass. Setpoint-layouten (tall over knapper) gjør
   at .temps-griden ikke trenger å stacke -- tallet får uansett full
   bredde i sin .setpoint-celle. */
@container roomcard (max-width: 240px) {
  .adj {
    width: 44px;
    height: 44px;
    min-height: 44px;
    font-size: 1.3rem;
  }
}

/* =========================================================================
   Heater list — switch-style toggle (not CTA-looking button)
   ========================================================================= */
.heaters {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin-top: 0.7rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--border);
}
.heater {
  display: grid;
  /* Venstre-zone (edit-btn med bilde+navn+wattage) = 1fr, toggle = auto */
  grid-template-columns: 1fr auto;
  gap: 0.65rem;
  align-items: center;
  background: var(--bg-inset);
  padding: 0.45rem 0.7rem;
  border-radius: 10px;
}
/* Venstre-zonen er en knapp som åpner wattage-picker. Hele zonen er
   tappbar -- ikke bare det 44x44px bildet -- for stor tap-target på mobil.
   Button-reset så font/farge arves; subtil hover-tint + focus-ring
   signaliserer interaktivitet. */
.heater-edit-btn {
  display: grid;
  grid-template-columns: 40px 1fr;
  gap: 0.65rem;
  align-items: center;
  background: transparent;
  border: none;
  padding: 0.15rem 0.1rem;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  min-width: 0;
  border-radius: 8px;
  -webkit-tap-highlight-color: transparent;
}
.heater-edit-btn:hover {
  background: color-mix(in oklab, var(--fg) 6%, transparent);
}
.heater-edit-btn:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
.heater.offline,
.heater.disabled {
  opacity: 0.55;
}
/* Bildet selv blir greyscale så det er åpenbart "ikke i bruk" */
.heater.offline img,
.heater.disabled img {
  filter: grayscale(1) brightness(0.85);
}
.heater.disabled .heater-name { color: var(--fg-soft); }
.heater img {
  width: 44px; height: 44px;
  object-fit: contain;
  border-radius: 6px;
}
.heater-info { min-width: 0; }
.heater-name { font-weight: 600; font-size: 0.95rem; color: var(--fg); }
.heater-meta { font-size: 0.78rem; color: var(--muted); }

/* iOS-style switch — track + sliding knob. Skog green when ON, neutral OFF. */
.heater-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  background: var(--border-strong);
  width: 52px; height: 32px;
  border-radius: 999px;
  border: none;
  padding: 0;
  cursor: pointer;
  transition: background 180ms ease;
  flex-shrink: 0;
  min-height: 32px;
}
.heater-toggle::after {
  content: "";
  position: absolute;
  left: 3px; top: 3px;
  width: 26px; height: 26px;
  background: #ffffff;
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0,0,0,0.25);
  transition: transform 180ms ease;
}
.heater-toggle[aria-pressed="true"],
.heater-toggle[aria-checked="true"] { background: var(--on); }
.heater-toggle[aria-pressed="true"]::after,
.heater-toggle[aria-checked="true"]::after { transform: translateX(20px); }
.heater-toggle:disabled { opacity: 0.45; cursor: not-allowed; }
.heater-toggle:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }

/* =========================================================================
   Per-room Manuell/Program toggle. Pill segmented with brand fill on active.
   Smaller / less aggressive than before — it's a mode switch, not a CTA.
   ========================================================================= */
.mode-toggle {
  display: inline-flex;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  overflow: hidden;
  margin-bottom: 0.75rem;
  background: var(--bg-inset);
  padding: 3px;
  gap: 2px;
}
.mode-btn {
  background: transparent;
  color: var(--fg-soft);
  font-size: 0.85rem;
  font-weight: 600;
  padding: 0.4rem 1rem;
  border: none;
  border-radius: 999px;
  min-height: 36px;
  cursor: pointer;
  transition: background 100ms ease, color 100ms ease;
}
.mode-btn[aria-pressed="true"] {
  background: var(--brand);
  color: var(--accent-fg);
}

/* =========================================================================
   Bulk-aksjoner (alle/valgte rom) — collapsible section over rooms-grid.
   ========================================================================= */
.bulk-actions {
  margin: 0 0 1rem;
  padding: 0.6rem 1rem;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.bulk-actions > summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--fg);
  list-style: none;
  padding: 0.3rem 0;
}
.bulk-actions > summary::-webkit-details-marker { display: none; }
.bulk-actions > summary::before {
  content: "▸";
  display: inline-block;
  margin-right: 0.5rem;
  transition: transform 120ms ease;
  color: var(--muted);
}
.bulk-actions[open] > summary::before { transform: rotate(90deg); }
.bulk-rooms-wrap {
  border: none;
  padding: 0.5rem 0 0;
  margin: 0;
}
.bulk-rooms-wrap > legend {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  padding: 0;
}
.bulk-rooms-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0.5rem 0;
}
.bulk-room-item {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.45rem 0.85rem;
  background: var(--bg-inset);
  border-radius: 999px;
  font-size: 0.95rem;
  cursor: pointer;
  min-height: 40px;  /* større tap-target -- nær Apple HIG 44pt */
}
.bulk-room-item input {
  accent-color: var(--brand);
  margin: 0;
  width: 22px;
  height: 22px;  /* større enn 18px default for tommel-vennlighet */
}
/* Header-rad: rom-pills til venstre, "Alle / Ingen"-snarveier til høyre
   (eller under på mobil). Tar mindre vertikal plass enn forrige layout. */
.bulk-rooms-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  margin-bottom: 0.85rem;
}
.bulk-rooms-header .bulk-rooms-list {
  flex: 1 1 auto;
  margin: 0;
}
.bulk-room-actions {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  flex-shrink: 0;
}
.bulk-sep { color: var(--border); }
.link-small {
  background: none;
  border: none;
  padding: 0.25rem 0.1rem;
  font-size: 0.85rem;
  color: var(--muted);
  cursor: pointer;
  font-family: inherit;
  text-decoration: none;
  transition: color 100ms ease;
}
.link-small:hover { color: var(--brand); }

/* Action-list i definition-list-stil: hver handling er én rad med
   label-kolonne til venstre, kompakt input + button-cluster til høyre.
   Mer minimalistisk enn forrige 3+2+2-button-grid. */
.bulk-actions-list {
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.bulk-action-row {
  display: grid;
  grid-template-columns: minmax(120px, max-content) 1fr;
  align-items: center;
  gap: 0.85rem;
  padding: 0.5rem 0;
  border-top: 1px solid var(--border);
}
.bulk-action-row:first-of-type { border-top: none; }
.bulk-action-row > dt {
  font-size: 0.85rem;
  color: var(--muted);
  margin: 0;
}
.bulk-action-row > dt label { margin: 0; cursor: default; color: inherit; font-size: inherit; }
.bulk-action-row > dd {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
}
.bulk-input {
  padding: 0.4rem 0.65rem;
  background: var(--bg-inset);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 8px;
  min-height: 36px;
  font-family: inherit;
  font-size: 0.95rem;
  max-width: none;
  width: auto;
}
.bulk-input[type="number"] { width: 5.5rem; text-align: center; }
.bulk-unit { color: var(--muted); font-size: 0.85rem; margin: 0 0.3rem 0 -0.1rem; }
.bulk-action-btn {
  padding: 0.4rem 0.85rem;
  background: var(--bg-inset);
  border: 1px solid var(--border);
  color: var(--fg);
  border-radius: 8px;
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
  min-height: 36px;
  transition: background 100ms ease, border-color 100ms ease;
}
.bulk-action-btn:hover {
  background: var(--bg-inset-strong, var(--bg-elev));
  border-color: var(--border-strong);
}
.bulk-action-btn:active { transform: scale(0.97); }
.bulk-action-btn[disabled] { opacity: 0.45; cursor: not-allowed; }
.bulk-action-btn.primary-tint {
  background: var(--brand-soft);
  border-color: color-mix(in oklab, var(--brand) 30%, transparent);
  color: var(--brand);
}
.bulk-action-btn.primary-tint:hover {
  background: var(--brand);
  color: var(--accent-fg);
  border-color: var(--brand);
}

/* "Beha styrer" -- vi enforcer ikke. Vis hele toggelen dempet (begge tabs
   ser inaktive ut) så bruker ser at de IKKE er på vårt manuell- eller
   program-modus. Trykk en av tab-ene for å ta over kontrollen. */
.mode-toggle--beha {
  opacity: 0.55;
  border-style: dashed;
  background: transparent;
}
.mode-toggle--beha .mode-btn {
  color: var(--fg-soft);
}

/* PROGRAM-summary er nå selve åpne-editor-knappen (separat "Endre program"-
   knapp fjernet 2026-05-25). Button-reset så font/text-align arves fra
   parent, cursor signaliserer klikkbarhet, hover-fyll gjør hele blokken
   til en tydelig affordance. Pencil-ikonet i hjørnet er en stille hint
   for touch-brukere som ikke har hover. */
.program-summary {
  font: inherit;
  text-align: left;
  cursor: pointer;
  position: relative;
  width: 100%;
}
.program-summary:hover {
  background: color-mix(in oklab, var(--on) 10%, transparent);
}
.program-summary:focus-visible {
  outline: 2px solid var(--on);
  outline-offset: 2px;
}
/* Pencil sitter INLINE rett etter "Program"-label-teksten (ikke absolute
   i hjørnet -- det overlappet med temp-tallet). Subtil opacity så det
   ikke konkurrerer med selve label-bokstavene. */
.program-summary-hint {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: 0.3rem;
  width: 12px;
  height: 12px;
  vertical-align: -1px;
  color: var(--on);
  opacity: 0.6;
  pointer-events: none;
}
.program-summary-hint svg { width: 100%; height: 100%; }

/* Program-mode summary — visuelt SUBORDINAT til .now (INNE NÅ). Bruker
   kan ikke tweake denne direkte (må åpne editor), så det er kontekstuell
   info, ikke et fokuspunkt. Én hero-tall per card-regel: INNE NÅ vinner,
   PROGRAM NÅ støtter. Transparent bakgrunn + tynn grønn border + ~60% font
   av hero gir tydelig "dette er målet vi sikter på" uten å konkurrere. */
.program-summary {
  background: transparent;
  border: 1px solid color-mix(in oklab, var(--on) 28%, transparent);
  border-radius: 12px;
  padding: 0.45rem 0.9rem;
  color: var(--on);
  font-weight: 600;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.8rem;
}
.program-summary .label {
  font-size: 0.7rem;
  color: var(--on);
  opacity: 0.85;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 700;
  white-space: nowrap;
  flex-shrink: 0;
}
.program-summary .big {
  color: var(--on);
  /* Subordinat til .now -- ~60% av hero-størrelse. Container query
     beholder relativ skalering på smale cards. */
  font-size: clamp(1.2rem, 11cqw, 1.7rem);
  font-weight: 600;
  flex-shrink: 0;
}
/* Aktivt slot-navn (2026-05-25 owner-request). Sitter mellom "PROGRAM ✎"
   og temp-tallet, flex-grow så den krymper først ved trange cards. Lange
   brukerdefinerte navn ("Morgen i juleferien") trunkeres med ellipsis. */
.program-summary .program-slot-name {
  flex: 1 1 auto;
  min-width: 0;
  text-align: center;
  font-size: clamp(0.72rem, 4.5cqw, 0.85rem);
  font-weight: 500;
  color: color-mix(in oklab, var(--on) 75%, transparent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: 0.02em;
}

/* Boost-summary -- samme inline-layout som program-summary, brand-rød tint. */
.boost-summary {
  background: var(--brand-soft);
  border-radius: 12px;
  padding: 0.7rem 0.9rem;
  color: var(--brand);
  font-weight: 600;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.8rem;
}
.boost-summary .label {
  font-size: 0.75rem;
  color: var(--brand);
  opacity: 0.85;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 700;
  white-space: nowrap;
  flex-shrink: 0;
}
.boost-summary .big { color: var(--brand); }
.boost-note {
  font-size: 0.85rem;
  text-align: center;
  margin: 0.5rem 0 0;
  color: var(--muted);
  font-style: italic;
}
/* "Avbryt boost"-knapp under boost-pillen. Subtil men touch-friendly. */
.boost-cancel-btn {
  display: block;
  width: 100%;
  margin: 0.65rem 0 0;
  padding: 0.55rem 0.9rem;
  background: var(--bg-inset);
  border: 1px solid color-mix(in oklab, var(--brand) 35%, transparent);
  color: var(--brand);
  border-radius: 10px;
  font-weight: 600;
  font-size: 0.92rem;
  cursor: pointer;
  font-family: inherit;
  min-height: 40px;
  transition: background 120ms ease, border-color 120ms ease;
}
.boost-cancel-btn:hover {
  background: var(--brand-soft);
  border-color: var(--brand);
}
.boost-cancel-btn:active { transform: scale(0.98); }

/* =========================================================================
   Program dialog table
   ========================================================================= */
/* Wattage-picker: 3 store kort-knapper i en 3-kol-grid. Tile-størrelse
   ~110x110 -- funker fra iPhone SE (320px viewport, dialog 92% bred =
   ~294px, /3 = 98px tile + gap) til desktop. Auto-fit ville stacket på
   ultra-smal, men 3 i rad er ALLTID lesbart selv på SE. */
dialog#wattage-dialog {
  border: none;
  border-radius: var(--radius);
  background: var(--card-bg);
  color: var(--fg);
  padding: 1.5rem 1.25rem 1.25rem;
  max-width: 92%;
  width: 420px;
  box-shadow: var(--shadow-lg);
  max-height: min(90vh, 90svh);
  overflow-y: auto;
}
dialog#wattage-dialog::backdrop {
  background: rgba(20,17,15,0.55);
  backdrop-filter: blur(2px);
}
.wattage-form h3 {
  margin: 0 0 0.25rem;
  font-size: 1.15rem;
}
.wattage-form .muted {
  margin: 0 0 0.6rem;
  font-size: 0.85rem;
}
.wattage-picker {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.55rem;
  margin: 0.8rem 0 1rem;
}
.wattage-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  padding: 0.85rem 0.4rem;
  background: var(--bg-inset);
  border: 2px solid var(--border);
  border-radius: 12px;
  cursor: pointer;
  font: inherit;
  color: var(--fg);
  min-height: 116px;
  transition: border-color 120ms ease, background 120ms ease, transform 80ms ease;
  -webkit-tap-highlight-color: transparent;
}
.wattage-tile img {
  width: 52px;
  height: 52px;
  object-fit: contain;
  flex-shrink: 0;
}
.wattage-tile-label {
  font-size: 0.9rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}
.wattage-tile:hover {
  border-color: var(--brand);
  background: var(--brand-soft);
}
.wattage-tile:active { transform: scale(0.96); }
.wattage-tile[aria-pressed="true"] {
  border-color: var(--brand);
  background: var(--brand-soft);
  color: var(--brand);
}
.wattage-tile:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

dialog#program-dialog {
  border: none;
  border-radius: var(--radius);
  background: var(--card-bg);
  color: var(--fg);
  padding: 1.5rem 1.25rem 1.25rem;
  max-width: 92%;
  width: 480px;
  box-shadow: var(--shadow-lg);
  /* svh tar høyde for iOS dynamic viewport (browser-chrome som skjuler/
     viser seg under scroll). min() faller tilbake til vh om svh ikke
     støttes. Innholdet over sticky-footer scroller; Lagre-knappen står. */
  max-height: min(90vh, 90svh);
  overflow-y: auto;
}
dialog#program-dialog::backdrop {
  background: rgba(20,17,15,0.55);
  backdrop-filter: blur(2px);
}
/* Program-slots: kort-per-tidspunkt-layout (2026-05-25 refactor fra
   tabell). Hvert kort har label + delete på topp-raden, tid/temp/på
   på bunn-raden. Funker på iPhone SE (320px) uten horisontal scroll --
   tabellen krevde 5 kolonner og dyttet delete-knappen utenfor viewport. */
.program-slots {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 1rem 0;
}
.program-slot {
  background: var(--bg-inset);
  border-radius: 10px;
  padding: 0.6rem 0.7rem;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  border: 1px solid var(--border);
}
.program-slot-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.program-slot-head .slot-label {
  flex: 1;
  min-width: 0;          /* tillat shrink under content-width */
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.5rem 0.65rem;
  font: inherit;
  font-size: 1rem;       /* >=16px -- forhindrer iOS auto-zoom */
  color: var(--fg);
  font-weight: 600;
}
.program-slot-head .slot-label:focus {
  border-color: var(--brand);
  outline: none;
}
.program-slot-body {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex-wrap: wrap;
}
.slot-field {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
}
.slot-field-label {
  font-size: 0.8rem;
  color: var(--muted);
  font-weight: 600;
  letter-spacing: 0.04em;
}
.program-slot-body input[type="time"],
.program-slot-body input[type="number"] {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.45rem 0.6rem;
  font: inherit;
  font-size: 1rem;       /* >=16px -- forhindrer iOS auto-zoom på focus */
  color: var(--fg);
  font-variant-numeric: tabular-nums;
  margin: 0;
  min-height: 38px;
}
.program-slot-body input[type="time"] { width: 6.5rem; }
.program-slot-body input[type="number"] { width: 4.8rem; }
.slot-enabled {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.9rem;
  margin: 0;
  cursor: pointer;
}
.slot-enabled-check {
  width: 20px; height: 20px;
  accent-color: var(--brand);
  margin: 0;
}

/* =========================================================================
   Reorder dialog (2026-05-25 v2 — Discord/iOS-pattern).
   Dedikert modal med liste av rom-navn + drag-handle (⋮⋮). Bruker holder på
   gripen og drar opp/ned; nabo-rader sklir vekk underveis for å vise hvor
   rommet havner. Auto-save når pointer slippes. "Ferdig"-knapp lukker.
   touch-action:none på .reorder-grip hindrer side-scroll mens man drar.
   ========================================================================= */
dialog#reorder-dialog {
  border: none;
  border-radius: var(--radius);
  background: var(--card-bg);
  color: var(--fg);
  padding: 1.5rem 1.25rem 1.25rem;
  max-width: 92vw;
  width: 420px;
  box-shadow: var(--shadow-lg);
  max-height: min(90vh, 90svh);
  overflow: hidden;
}
/* [open]-selector unngår å overstyre browser-default `display: none` på
   lukket dialog (display: flex utenfor [open] gjorde at dialogen var
   synlig hele tiden). Dialogen er en flex-column-container; listen får
   flex:1 og scroller internt i stedet for at hele dialogen scroller.
   "Ferdig"-knappen er ALLTID synlig nederst -- også på iPhone landscape
   med 430px tilgjengelig høyde der dialog ellers ble klemt til 1 rad. */
dialog#reorder-dialog[open] {
  display: flex;
  flex-direction: column;
}
dialog#reorder-dialog::backdrop {
  background: rgba(20,17,15,0.55);
  backdrop-filter: blur(2px);
}
.reorder-form {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  min-width: 0;
  width: 100%;
  flex: 1 1 auto;
  min-height: 0;          /* slipper child flex-1 å overflowe */
}
.reorder-list {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  flex: 1 1 auto;
  min-height: 0;          /* lar overflow-y faktisk fungere */
  overflow-y: auto;
}
.reorder-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.85rem 0.4rem 0.85rem 1rem;
  background: color-mix(in oklab, var(--on) 4%, var(--card, var(--bg)));
  border: 1px solid color-mix(in oklab, var(--on) 10%, transparent);
  border-radius: 12px;
  transition: transform 0.18s cubic-bezier(0.2, 0.9, 0.3, 1.1),
              box-shadow 0.18s, background 0.18s;
  will-change: transform;
  user-select: none;
  min-width: 0;
}
.reorder-row-name {
  font-size: 1rem;
  font-weight: 600;
  color: var(--on);
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.reorder-grip {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 5px 5px;
  align-content: center;
  justify-content: center;
  width: 52px;            /* over 44pt HIG-minimum */
  height: 52px;
  padding: 14px 12px;
  background: transparent;
  border: none;
  cursor: grab;
  /* Tydeligere farge så prikkene faktisk SES på mobil (var altfor lyse før).
     Bruker brand-coral ved hover/active for å signalisere "denne er drabar". */
  color: color-mix(in oklab, var(--on) 75%, transparent);
  touch-action: none;     /* hindrer side-scroll mens man drar */
}
.reorder-grip:active,
.reorder-grip:hover {
  color: var(--brand, var(--on));
}
.reorder-grip:active { cursor: grabbing; }
.reorder-grip .grip-dot {
  display: block;
  width: 5px;
  height: 5px;
  background: currentColor;
  border-radius: 50%;
}
.reorder-item--dragging {
  background: color-mix(in oklab, var(--brand-soft, var(--on)) 18%, var(--card, var(--bg)));
  box-shadow: 0 8px 20px -6px rgba(0, 0, 0, 0.35);
  z-index: 10;
  transition: none;       /* mens man drar skal det følge fingeren 1:1 */
}
/* Overstyr boost-actions inni reorder-dialogen. De andre dialogene
   (boost-dialog, program-dialog) bruker .boost-actions som sticky-footer
   med negative margin + padding for scrollable content; her trenger vi
   bare en kompakt knapperad nederst som ikke eter plass. */
dialog#reorder-dialog .boost-actions {
  position: static;
  margin: 0.5rem 0 0;
  padding: 0;
  border-top: none;
  box-shadow: none;
  background: transparent;
  justify-content: stretch;
  flex: 0 0 auto;         /* knapperaden tar fast plass; listen får resten */
}
.reorder-item--dragging .reorder-grip {
  cursor: grabbing;
  color: var(--brand, var(--on));
}
@media (max-width: 480px) {
  /* På smale skjermer trekker vi inn dialog-padding så hele listen får
     mer plass; gripen er litt smalere men prikkene står like store. */
  dialog#reorder-dialog { padding: 1.25rem 0.85rem 1rem; }
  .reorder-item { padding: 0.85rem 0.25rem 0.85rem 0.85rem; }
  .reorder-grip { width: 44px; padding: 14px 8px; }
}
@media (max-height: 500px) {
  /* Landscape mobil (iPhone Pro Max ~430px høyde): kompakt-modus så
     vi får inn 3-4 rader i listen i stedet for 1. Skjuler hjelpe-tekst
     (gripen er nok hint) og strammer padding overalt. */
  dialog#reorder-dialog { padding: 0.85rem 1rem 0.85rem; }
  dialog#reorder-dialog h3 { margin: 0; font-size: 1rem; }
  dialog#reorder-dialog > .reorder-form > .muted { display: none; }
  .reorder-form { gap: 0.4rem; }
  .reorder-item { padding: 0.5rem 0.4rem 0.5rem 0.85rem; }
  .reorder-row-name { font-size: 0.95rem; }
  .reorder-grip { width: 44px; height: 44px; padding: 11px 9px; gap: 4px; }
  .reorder-grip .grip-dot { width: 4px; height: 4px; }
}

/* Option C (2026-05-25): "Ovn på"-ukrysset slot signaliserer "ved dette
   tidspunktet skrus ovnen AV". TIDSPUNKTET må forbli lesbart i full styrke
   så brukeren ser NÅR av-eventet skjer (owner-pref 2026-05-25 etter at
   den tidligere opacity:0.75 dimmet hele kortet inkl. klokkeslettet).
   Vi bruker derfor IKKE opacity på selve .program-slot--off (det ville
   uunngåelig dimme tid-input også), men markerer i stedet med:
     - subtil bakgrunns-tint som forsterker "denne raden er noe annet"
     - label får redusert opacity (egen regel)
     - temp-input er disabled + grålig
     - klokkeslett-input forblir UENDRET (full styrke) */
.program-slot--off {
  background: color-mix(in oklab, var(--bg-inset, var(--bg)) 60%, transparent);
}
.program-slot--off .slot-label {
  opacity: 0.55;
}
.program-slot--off .slot-temp,
.program-slot .slot-temp:disabled {
  color: var(--muted);
  opacity: 0.55;
  cursor: not-allowed;
  background: var(--bg-inset);
}
.program-slot .slot-temp:disabled::-webkit-inner-spin-button {
  opacity: 0.3;
}

/* =========================================================================
   Program dialog — day picker (multi-select) + variable slot rows.
   ========================================================================= */
.program-days {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0.75rem 0 0.5rem;
}
.day-btn {
  min-width: 48px;
  padding: 0.5rem 0.7rem;
  border-radius: 10px;
  border: 1.5px solid var(--border);
  background: var(--bg-inset);
  color: var(--muted);
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease, transform 80ms ease;
  min-height: 40px;
  font-family: inherit;
}
.day-btn:hover { border-color: var(--brand); color: var(--fg); }
.day-btn:active { transform: scale(0.96); }
.day-btn--active {
  background: var(--brand);
  color: var(--accent-fg);
  border-color: var(--brand);
}
.day-btn--active:hover { background: var(--brand-deep); border-color: var(--brand-deep); color: var(--accent-fg); }

.slot-delete-btn {
  /* 44x44 hit target -- Apple HIG minimum, matches our other interactive
     controls. Previous 32px was a tilfeldig-sletting risk in program
     dialog (UX audit 2026-05-25). */
  width: 44px; height: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  border: 1px solid transparent;
  color: var(--error);
  font-size: 1.35rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 8px;
  touch-action: manipulation;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
  font-family: inherit;
}
.slot-delete-btn:hover { background: var(--error-soft); color: var(--error); border-color: color-mix(in oklab, var(--error) 30%, transparent); }
.slot-delete-btn:active { transform: scale(0.92); }

.program-add-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin: 0.5rem 0 0.9rem;
  padding: 0.4rem 0.85rem;
  background: var(--bg-inset);
  border: 1px dashed var(--border);
  color: var(--fg);
  border-radius: 10px;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  min-height: 38px;
}
.program-add-btn:hover { border-color: var(--brand); border-style: solid; background: var(--on-soft); color: var(--brand); }

/* =========================================================================
   Boost — topbar nav button (was floating FAB pre-v4). Brand-fill so it's
   the strongest signal in the nav. Aligned with Innstillinger + Logg av.
   "Ikke flyt i veien" — owner feedback 2026-05-24.
   ========================================================================= */
.topbar-nav .link.boost-link {
  background: var(--brand);
  color: var(--accent-fg);
  padding: 0.4rem 0.85rem;
  border-radius: 999px;
  font-weight: 600;
  min-height: 36px;
  border: none;
  font-family: inherit;
  cursor: pointer;
  transition: background 120ms ease, transform 80ms ease;
}
.topbar-nav .link.boost-link:hover {
  background: var(--brand-deep);
  color: var(--accent-fg);
}
.topbar-nav .link.boost-link:active { transform: scale(0.96); }

/* Mobile: when topbar-menu collapses into the hamburger drawer, the boost
   button gets the full drawer-row width + bigger tap-target. */
@media (max-width: 719px) {
  .topbar-menu .link.boost-link {
    width: 100%;
    justify-content: center;
    min-height: 44px;
    padding: 0.6rem 0.85rem;
  }
}

/* =========================================================================
   Boost dialog
   ========================================================================= */
dialog#boost-dialog {
  border: none;
  border-radius: var(--radius);
  background: var(--card-bg);
  color: var(--fg);
  padding: 1.5rem 1.25rem 1.25rem;
  max-width: 92%;
  width: 380px;
  box-shadow: var(--shadow-lg);
  max-height: min(90vh, 90svh);
  overflow-y: auto;
}
dialog#boost-dialog::backdrop {
  background: rgba(20,17,15,0.55);
  backdrop-filter: blur(2px);
}
.boost-form h3 { margin: 0 0 0.5rem; font-size: 1.2rem; display: inline-flex; align-items: center; gap: 0.5rem; }
.boost-form label { display: block; margin: 1rem 0 0.5rem; max-width: none; }
.boost-form input[type="number"] { max-width: none; }
.boost-form fieldset { border: none; padding: 0; margin: 1.25rem 0 0; }
.boost-form legend {
  font-size: 0.72rem;
  color: var(--muted);
  margin-bottom: 0.5rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.boost-durations {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.5rem;
}
.duration-btn {
  padding: 0.75rem 0.5rem;
  font-size: 1rem;
  font-weight: 600;
  border: 1.5px solid var(--border-strong);
  background: var(--card-bg);
  color: var(--fg);
  border-radius: var(--radius-sm);
  cursor: pointer;
  min-height: 48px;
}
.duration-btn[aria-pressed="true"] {
  background: var(--brand);
  color: var(--accent-fg);
  border-color: var(--brand);
}
/* Boost room picker — checkbox list inside the dialog */
.boost-rooms {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  max-height: 220px;
  overflow-y: auto;
  padding: 0.5rem 0.25rem;
  background: var(--bg-inset);
  border-radius: var(--radius-sm);
}
.boost-room-row {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  margin: 0;
  padding: 0.55rem 0.65rem;
  cursor: pointer;
  font-weight: 500;
  font-size: 0.95rem;
  border-radius: 6px;
  max-width: none;
  transition: background 100ms ease;
}
.boost-room-row:hover { background: var(--brand-soft); }
.boost-room-check {
  width: 22px; height: 22px;
  margin: 0;
  accent-color: var(--brand);
  flex-shrink: 0;
}
.boost-room-actions {
  display: flex;
  gap: 1.25rem;
  margin-top: 0.55rem;
  justify-content: flex-end;
}
.link-small {
  background: none;
  color: var(--brand);
  padding: 0.2rem 0.4rem;
  font-size: 0.85rem;
  font-weight: 500;
  border: none;
  cursor: pointer;
  min-height: 0;
}
.link-small:hover { text-decoration: underline; }

/* Footer-aksjoner: ALLTID synlig nederst i dialog. Tidligere kunne lange
   program/boost-dialoger gjøre Lagre-knappen utilgjengelig under
   skjermkanten -- bruker måtte scrolle for å finne den. position:sticky
   gjør at den følger med nederst i dialogens scroll-container; innholdet
   over scroller, knappene står stille.
   Negativ margin-bunn + horisontal margin-strekk: footeren fyller dialogens
   bunnkant visuelt (hjelper også å skjule scrollbar-clipping). Top-shadow
   gir myk "mer over"-hint. */
.boost-actions {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  align-items: center;
  position: sticky;
  bottom: -1.25rem;  /* offset dialog's padding-bottom */
  margin: 1.25rem -1.25rem -1.25rem;
  padding: 0.85rem 1.25rem 1.25rem;
  background: var(--card-bg);
  border-top: 1px solid var(--border);
  box-shadow: 0 -10px 16px -8px rgba(0, 0, 0, 0.35);
  z-index: 1;
}
.boost-actions .primary {
  flex: 1;
  background: var(--brand);
  color: var(--accent-fg);
}
.boost-actions .link {
  color: var(--muted);
}

/* =========================================================================
   Topbar nav + hamburger menu (mobile hamburger, desktop inline). Menu
   slides down under the topbar when open on mobile.
   ========================================================================= */
.hamburger {
  background: transparent;
  border: none;
  color: var(--fg);
  display: inline-flex;
  flex-direction: column;
  justify-content: space-around;
  width: 38px; height: 38px;   /* = dashboardets icon-btn, så topbar-høyden matcher */
  padding: 9px 7px;
  cursor: pointer;
  border-radius: 999px;
}
.hamburger:hover { background: var(--brand-soft); }
.hamburger span {
  display: block;
  width: 100%;
  height: 2px;
  background: var(--fg);
  border-radius: 2px;
  transition: transform 180ms ease, opacity 120ms ease;
}
.hamburger[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.hamburger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.hamburger[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* Meny = flytende dropdown-KORT på ALLE bredder — samme affordanse som
   dashboardet (eier 2026-08-11: den inline horisontale nav-en på desktop
   «ødela symmetrien»). Hamburgeren er alltid synlig, aldri inline-variant.
   Dashboard-knappen ligger i .top-actions ved siden av hamburgeren.
   Kortet ankres til .top-actions (position:relative) → høyrejustert rett under
   hamburgeren i alle bredder. Åpnes/lukkes via data-open (nav-menu.js). */
.topbar-menu {
  position: absolute;
  top: calc(100% + 12px);   /* under hamburgeren + topbarens padding-bunn */
  right: 0;
  z-index: 30;
  min-width: 210px;
  max-width: min(280px, calc(100vw - 16px));
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  padding: 0 0.5rem;
  max-height: 0;
  overflow: hidden;
  transition: max-height 200ms ease;
}
.topbar-menu[data-open="true"] {
  max-height: 75vh;
  padding: 0.4rem 0.5rem;
  overflow-y: auto;
}
/* Lukket (max-height:0 for slide-animasjon): skjul kant + skygge så en 0-høyde-
   boks ikke etterlater en tynn strek under topbaren. */
.topbar-menu:not([data-open="true"]) { border-color: transparent; box-shadow: none; }
/* topbar-nav sine lenker blir direkte rader i kortet (display:contents). */
.topbar-nav { display: contents; }
.logout-form { margin: 0; width: 100%; }
/* Rader: EKSAKT samme som dashboardets .menu-rader (eier «lik i font, størrelse,
   tekstfarge, tykkelse»): 14px / 650 / venstrejustert. text-align:left retter at
   <button> arver browserens sentrering (Tema/Logg av var sentrert, lenkene ikke). */
.topbar-nav a.link, .topbar-nav button.link, .topbar-nav span.link,
.topbar-menu .logout-form button {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  text-align: left;
  gap: 9px;
  width: 100%;
  padding: 10px 11px;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 650;
  color: var(--fg);
  text-decoration: none;
  background: none;
  border: none;
  cursor: pointer;
  min-height: 44px;
  box-sizing: border-box;
}
.topbar-nav a.link:hover, .topbar-nav button.link:hover,
.topbar-menu .logout-form button:hover { background: var(--brand-soft); }
.topbar-nav .link svg,
.topbar-menu .logout-form button svg { flex: 0 0 auto; width: 17px; height: 17px; color: var(--muted); }
/* Gjeldende side: markert (ikke klikkbar), ingen hover; ikonet arver coral. */
.topbar-nav .link.is-current,
.topbar-nav .link.is-current:hover {
  color: var(--brand);
  cursor: default;
  background: none;
}
.topbar-nav .link.is-current svg { color: var(--brand); }
/* Skillelinjer + footer — speiler dashboardets .menu hr / .menu-copy. */
.topbar-menu hr {
  border: none;
  border-top: 1px solid var(--border);
  margin: 5px 6px;
  width: auto;
}
.menu-copy {
  padding: 10px 11px 5px;
  margin-top: 4px;
  border-top: 1px solid var(--border);
  font-size: 11px;
  color: var(--muted);
  text-align: center;
  line-height: 1.6;
}
.menu-copy a { color: var(--muted); text-decoration: underline; font-weight: 600; }
.menu-copy a:hover { color: var(--brand); }

/* Back-link variant — visible on mobile WITHOUT opening hamburger, sits
   directly inside topbar (not inside .topbar-menu collapsing wrapper). */
.topbar-back {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--fg-soft);
  text-decoration: none;
  font-size: 0.95rem;
  font-weight: 500;
  padding: 0.4rem 0.75rem;
  border-radius: 8px;
  min-height: 44px; /* 44pt-gulvet resten av appen håndhever */
}
.topbar-back:hover { color: var(--brand); background: var(--brand-soft); }

/* =========================================================================
   Settings page (/innstillinger) — minimalistic, segmented controls, tight
   layout. Auto-saves on radio change via static/js/settings.js.
   Desktop: 2-column grid for innstillings-kortene side-by-side.
   ========================================================================= */
.settings-grid {
  display: flex;
  flex-direction: column;
  gap: 0;
}
@media (min-width: 720px) {
  .settings-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.25rem;
    align-items: start;
  }
  .settings-grid .card { margin-bottom: 0; }
  .settings-grid > .full { grid-column: 1 / -1; }
}

.setting-form-tight { margin: 0; }


button.tight {
  padding: 0.55rem 1.2rem;
  font-size: 0.9rem;
  font-weight: 600;
  white-space: nowrap;
  min-height: 40px;
  width: auto;
  max-width: none;
}

/* Banner — compact variant inside settings page */
.banner.compact {
  padding: 0.6rem 0.9rem;
  margin-bottom: 1rem;
  font-size: 0.9rem;
}
/* Fade-out applied by settings.js after a "Lagret."-banner has been visible
   long enough. CSS-only (avoids style-src 'self' CSP violation). */
.banner-fading {
  opacity: 0;
  transition: opacity 400ms ease;
}

/* Sammenleggbar seksjon — summary er nå en ordentlig korttittel (matcher
   dashboardets seksjonsvekt), ikke en dempet lenke. */
.collapsed-section details summary {
  cursor: pointer;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--fg);
  letter-spacing: -0.01em;
  list-style: none;
  padding: 0.15rem 0;
  display: flex;
  align-items: center;
  gap: 0.55rem;
}
.collapsed-section details summary::-webkit-details-marker { display: none; }
.collapsed-section details summary::before {
  content: "▸";
  display: inline-block;
  transition: transform 160ms ease;
  color: var(--brand);
  font-size: 0.8em;
}
.collapsed-section details[open] summary::before { transform: rotate(90deg); }
.collapsed-section details[open] form { margin-top: 1rem; }


/* Empty state */
.rooms-grid .muted {
  grid-column: 1 / -1;
  text-align: center;
  padding: 2rem 1rem;
  font-style: italic;
}

/* Status-linje i topbaren pa undersidene (samme tall som dashboardet) */
/* Logo + status samlet til venstre (2026-08-10, matcher dashboardet). Status
   sitter nå rett ved siden av ikonet, ikke skjøvet helt til høyre. */
/* Brand-omradet = dashboardets (logo + «Hytten» over farget status). px-baserte
   clamp = uavhengig av root-font, hentet 1:1 fra dashboard-v2.css .brand/.brand-sub. */
.topbar-brandrow { display: flex; align-items: center; gap: 10px; min-width: 0; flex: 1 1 auto; }
.brand-col { display: flex; flex-direction: column; line-height: 1.05; min-width: 0; }
.brand-name { font-size: clamp(16px, 4.6vw, 20px); font-weight: 800; letter-spacing: -0.3px; color: var(--fg); }
.topbar-status { font-size: clamp(10.5px, 3vw, 11.5px); color: var(--muted); margin-top: 3px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar-status b { color: var(--coral-text); font-weight: 750; }
.topbar-status b.tf { color: var(--frost-text); }  /* frost-tallet blått, som frostvakt */
.topbar-status:empty { display: none; }
/* Pre-auth (login/recovery rendrer ogsa brandrow): kun logoen, ingen «Hytten» */
body.auth-page .brand-name { display: none; }
/* Back-link + logout-gruppe skyves til høyre (space-between på topbar-inner
   gjør resten). */
.topbar-inner > .topbar-back { margin-left: auto; }

/* --- Tilkoblings-assistent (/tilkobling, 2026-08-07) ---------------------- */
.tilkobling-intro h2 { display: flex; align-items: center; gap: 8px; margin: 0 0 6px; }
.tilkobling-sweep {
  display: flex; align-items: center; gap: 8px;
  margin: 10px 0 0; font-size: 0.85rem; color: var(--muted);
}
.sweep-dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--on); flex: none;
  animation: sweep-pulse 2s ease-in-out infinite;
}
@keyframes sweep-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.25; } }
.sweep-error .sweep-dot { background: var(--warn); animation: none; }
.sweep-error { color: var(--warn); }

.tilkobling-list { display: flex; flex-direction: column; gap: 8px; margin: 14px 0; }
.heater-row {
  display: flex; align-items: center; gap: 12px;
  background: var(--card-bg); border-radius: 12px; padding: 12px 14px;
}
.heater-row.flash { animation: row-flash 1s ease-in-out 4; }
@keyframes row-flash {
  0%,100% { background: var(--card-bg); }
  50% { background: var(--on-soft); }
}
.status-dot { width: 14px; height: 14px; border-radius: 50%; flex: none; }
.status-dot.online { background: var(--on); box-shadow: 0 0 8px var(--on); }
.status-dot.offline { background: var(--warn); }
.status-dot.gone { background: var(--muted); }
.heater-row-main { flex: 1; min-width: 0; font-size: 0.95rem; }
.heater-mac {
  display: block; font-size: 0.7rem; color: var(--muted);
  font-variant-numeric: tabular-nums; letter-spacing: 0.04em;
}
.heater-row-state { text-align: right; flex: none; max-width: 46%; }
.state-label { display: block; font-weight: 700; font-size: 0.8rem; }
.state-label.online { color: var(--on); }
.state-label.offline { color: var(--warn); }
.state-label.gone { color: var(--muted); }
.state-age { display: block; font-size: 0.72rem; color: var(--muted); }
.state-change { display: block; font-size: 0.72rem; color: var(--fg-soft); }
/* Rom-tildeling for uassignerte ovner (2026-08-16): velger + knapp i raden.
   ≥40px høyde = tappbart på iOS; wrappes under teksten på smale skjermer. */
.assign-row { display: inline-flex; gap: 6px; margin-top: 6px; align-items: center;
  flex-wrap: wrap; justify-content: flex-end; }
.assign-select { min-height: 38px; padding: 6px 8px; border-radius: 9px;
  border: 1px solid var(--border); background: var(--card-bg); color: var(--fg);
  font: inherit; font-size: 0.82rem; max-width: 150px; }
.assign-btn { min-height: 38px; padding: 6px 12px; border-radius: 9px;
  border: 1px solid color-mix(in srgb, var(--brand) 45%, transparent);
  background: color-mix(in srgb, var(--brand) 12%, var(--card-bg));
  color: var(--brand); font: inherit; font-size: 0.82rem; font-weight: 700;
  cursor: pointer; }
.assign-btn:disabled { opacity: 0.55; cursor: default; }

/* Kommando-tekst = trykk-for-å-kopiere (2026-08-16). */
.tilkobling-cmd { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.tilkobling-cmd:active { opacity: 0.6; }
.cmd-copied { color: var(--on); font-weight: 700; }

.tilkobling-log-card h3 { margin: 0 0 8px; font-size: 0.95rem; }
.tilkobling-log { list-style: none; margin: 0; padding: 0; font-size: 0.82rem; }
.tilkobling-log li { padding: 3px 0; border-bottom: 1px solid var(--bg-inset); }
.tilkobling-log li:last-child { border-bottom: none; }
.log-time { color: var(--muted); font-variant-numeric: tabular-nums; margin-right: 6px; }
.log-up { color: var(--on); }
.log-down { color: var(--warn); }
.log-gone { color: var(--muted); }

/* Ny stegflyt på /tilkobling (2026-08-10): nummererte kort-steg + kommando */
.tilkobling-guide-card h3 { margin: 0 0 10px; font-size: 1.02rem; }
.tilkobling-flow { list-style: none; counter-reset: steg; margin: 0; padding: 0; }
.tilkobling-flow > li {
  counter-increment: steg;
  position: relative;
  padding: 0 0 14px 44px;
  font-size: 0.92rem;
  line-height: 1.5;
}
.tilkobling-flow > li::before {
  content: counter(steg);
  position: absolute; left: 0; top: -2px;
  width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--brand-soft); color: var(--brand);
  font-weight: 700; font-size: 0.95rem;
}
.tilkobling-cmd {
  display: block; margin: 8px 0 4px; padding: 8px 10px;
  background: var(--bg-inset); border: 1px solid var(--border);
  border-radius: 8px; font-size: 0.85rem; overflow-x: auto; white-space: nowrap;
}
.tilkobling-nopy { font-size: 0.85rem; margin: 8px 0 6px; }
.tilkobling-nopy a { color: var(--brand); }
/* Moderne «Installer Python»-pille (Windows). */
.tilkobling-pybtn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 15px; border-radius: 999px;
  background: var(--brand-soft); color: var(--brand);
  border: 1px solid color-mix(in srgb, var(--brand) 30%, transparent);
  font-size: 0.9rem; font-weight: 650; text-decoration: none; white-space: nowrap;
}
.tilkobling-pybtn:hover { background: color-mix(in srgb, var(--brand) 15%, transparent); }
.tilkobling-pybtn svg { width: 16px; height: 16px; flex: 0 0 auto; }
.tilkobling-more summary { cursor: pointer; font-weight: 600; font-size: 0.9rem; }

/* --- Server-paringsmodus (/tilkobling, 2026-08-16) ------------------------ */
.pairing-mode-card h3 { display: flex; align-items: center; gap: 7px; margin: 0 0 8px; font-size: 1.02rem; }
.pairing-mode-card h3 svg { flex: 0 0 auto; }
.pairing-panel { margin-top: 12px; }
.pairing-state { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 0.9rem; font-weight: 650; }
.pairing-dot { width: 11px; height: 11px; border-radius: 50%; flex: none; background: var(--muted); }
.pairing-state.is-on { color: var(--on); }
.pairing-state.is-on .pairing-dot { background: var(--on); box-shadow: 0 0 9px var(--on); animation: sweep-pulse 2s ease-in-out infinite; }
.pairing-state.is-off { color: var(--muted); }
.pairing-countdown { margin: 8px 0 0; font-size: 0.82rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.pairing-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.pairing-btn {
  min-height: 44px; padding: 10px 18px; border-radius: 11px;
  font: inherit; font-size: 0.92rem; font-weight: 700; cursor: pointer;
  border: 1px solid transparent;
}
.pairing-btn:disabled { opacity: 0.55; cursor: default; }
.pairing-btn.primary {
  background: color-mix(in srgb, var(--brand) 16%, var(--card-bg));
  border-color: color-mix(in srgb, var(--brand) 45%, transparent);
  color: var(--brand);
}
.pairing-btn.danger {
  background: color-mix(in srgb, var(--warn) 14%, var(--card-bg));
  border-color: color-mix(in srgb, var(--warn) 45%, transparent);
  color: var(--warn);
}
.pairing-served { list-style: none; margin: 12px 0 0; padding: 0; font-size: 0.82rem; }
.pairing-served-head { color: var(--fg-soft); font-weight: 650; margin-bottom: 4px; }
.pairing-served-mac {
  color: var(--on); font-variant-numeric: tabular-nums; letter-spacing: 0.04em;
  padding: 2px 0;
}

/* Auto-pause-tilstand for /tilkobling-sweepen (2026-08-08) */
.sweep-paused { cursor: pointer; color: var(--warn); }
.sweep-paused .sweep-dot { background: var(--muted); animation: none; }

.tilkobling-steps { margin: 10px 0 6px; padding-left: 20px; font-size: 0.9rem; }
.tilkobling-steps li { margin-bottom: 8px; }
.tilkobling-steps code {
  background: var(--bg-inset); padding: 2px 6px; border-radius: 6px;
  font-size: 0.8rem; word-break: break-all;
}

/* ===================================================================
   Aktivitets-logg (/aktivitet) — moderne endrings-logg. Bruker base-
   sidens tokens (--card-bg/--fg/--muted/--brand/--border). 2026-08-11.
   =================================================================== */
.activity-wrap { max-width: 640px; margin: 0 auto; }
.page-title,
.activity-title { font-size: 1.4rem; font-weight: 800; letter-spacing: -0.3px; margin: 0 0 14px; color: var(--fg); }
.activity-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.activity-item {
  display: flex; align-items: flex-start; gap: 12px;
  background: var(--card-bg); border: 1px solid var(--border);
  border-radius: var(--radius-md, 14px); padding: 11px 14px;
}
.activity-item--fail { border-color: color-mix(in srgb, var(--error) 40%, var(--border)); }
.activity-dev { flex: 0 0 auto; font-size: 22px; line-height: 1.2; width: 30px; text-align: center; }
.activity-body { min-width: 0; flex: 1 1 auto; }
.activity-what { font-size: 0.98rem; font-weight: 700; color: var(--fg); }
.activity-fail-tag {
  font-size: 0.7rem; font-weight: 700; color: var(--error);
  background: var(--error-soft); padding: 1px 7px; border-radius: 999px; margin-left: 4px;
}
.activity-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 5px 7px;
  font-size: 0.8rem; color: var(--muted); margin-top: 3px; line-height: 1.4;
}
.activity-time { font-weight: 650; color: var(--fg-soft); }
.activity-sep { opacity: 0.5; }
.activity-ip { font-variant-numeric: tabular-nums; opacity: 0.85; }
.activity-empty {
  text-align: center; color: var(--muted); padding: 40px 20px;
  background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radius-md, 14px);
}
.activity-empty-ico { display: inline-flex; color: var(--brand); opacity: 0.7; margin-bottom: 8px; }
.activity-empty p { margin: 0; font-size: 0.92rem; line-height: 1.45; }

/* Hode: tittel + søk (søk fyller bredden på mobil, sitter ved siden på desktop). */
.activity-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-bottom: 14px; }
.activity-head .activity-title { margin: 0; }
.activity-search {
  display: flex; align-items: center; gap: 7px; flex: 1 1 220px; min-width: 0;
  background: var(--card-bg); border: 1px solid var(--border);
  border-radius: 999px; padding: 7px 14px;
}
.activity-search:focus-within { border-color: var(--brand); }
.activity-search-ico { opacity: 0.6; font-size: 0.9rem; flex: 0 0 auto; }
.activity-search input {
  flex: 1 1 auto; min-width: 0; border: none; background: none; outline: none;
  font: inherit; font-size: 0.92rem; color: var(--fg);
}
.activity-search input::placeholder { color: var(--muted); }
/* Søk + kalender + nullstill side om side (wrapper i .activity-head). */
.activity-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; flex: 1 1 260px; min-width: 0; margin-bottom: 14px; }
.activity-datepick {
  position: relative;   /* ankor for det gjennomsiktige date-inputet */
  display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto;
  background: var(--card-bg); border: 1px solid var(--border);
  border-radius: 999px; padding: 5px 14px; min-height: 44px;
}
.activity-datepick:focus-within { border-color: var(--brand); }
.activity-date-ico { display: inline-flex; opacity: 0.6; flex: 0 0 auto; }
.activity-date-text { font-size: 0.9rem; font-weight: 600; color: var(--fg); white-space: nowrap; }
/* Gjennomsiktig native date-input dekker HELE pillen → tapp åpner iOS-/desktop-
   velgeren, mens «Velg dag»-teksten alltid vises (iOS har ingen placeholder). */
.activity-datepick input[type="date"] {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; padding: 0; border: none; background: none; opacity: 0;
  cursor: pointer; -webkit-appearance: none; appearance: none;
}
.activity-reset {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px; min-height: 40px;
  padding: 6px 15px; border-radius: 999px; text-decoration: none;
  color: var(--brand); font-size: 0.9rem; font-weight: 650;
  background: var(--brand-soft);
  border: 1px solid color-mix(in srgb, var(--brand) 34%, transparent);
  -webkit-tap-highlight-color: transparent;
}
.activity-reset:hover { background: color-mix(in srgb, var(--brand) 18%, transparent); }
/* «Viser <dato>» får luft over (var negativ top-margin = klemt mot kontrollene). */
.activity-daysel { margin: 4px 4px 14px; color: var(--muted); font-size: 0.95rem; }
.activity-daysel b { color: var(--fg); font-weight: 700; }
/* Dag-overskrift (satt inn av JS). */
.activity-day {
  list-style: none; font-size: 0.72rem; font-weight: 750; letter-spacing: 0.5px;
  text-transform: uppercase; color: var(--muted); margin: 14px 4px 6px;
}
.activity-day:first-child { margin-top: 2px; }
.activity-noresults { text-align: center; color: var(--muted); padding: 24px 8px; margin: 0; font-size: 0.92rem; }
.activity-more {
  display: block; width: 100%; margin-top: 10px; padding: 11px; border-radius: var(--radius-md, 14px);
  border: 1px solid var(--border); background: var(--card-bg); color: var(--fg-soft);
  font: inherit; font-weight: 700; font-size: 0.88rem; cursor: pointer;
}
.activity-more:hover { border-color: var(--border-strong); color: var(--fg); }

/* ============================ TEMPERATUR-GRAF (fane på /aktivitet) ============================
   To faner (Temperatur/Endringer), rom-chips, tidsrom-velger + inline SVG-graf.
   Tokenene (--brand rust, --frost-text blå, --border, --card-bg) er alt tri-state
   i main.css, så grafen følger tema automatisk. Ingen inline-stil (CSP-trygt). */
.act-tabs { display: flex; gap: 6px; margin: 2px 0 16px; }
.act-tab {
  flex: 1; min-height: 44px; padding: 0 10px;
  border: 1px solid var(--border); border-radius: 12px; background: transparent;
  color: var(--muted); font: inherit; font-weight: 650; font-size: 0.95rem;
  cursor: pointer; transition: background .15s, color .15s, border-color .15s;
}
.act-tab[aria-selected="true"] {
  background: var(--card-bg); border-color: var(--brand); color: var(--fg);
  box-shadow: 0 1px 4px rgba(0,0,0,.06);
}
.act-tab:hover:not([aria-selected="true"]) { color: var(--fg); }
.act-panel { display: block; }

/* tidsrom-velger */
/* 4 range-knapper (Dag/Uke/Måned/6 mnd) må få plass på 390px. */
.tc-ranges { display: flex; gap: 5px; margin-bottom: 12px; }
.tc-range {
  flex: 1; min-width: 0; min-height: 40px; padding: 0 4px;
  border: 1px solid var(--border); border-radius: 10px; background: transparent;
  color: var(--muted); font: inherit; font-weight: 650;
  font-size: clamp(0.8rem, 3.2vw, 0.9rem); white-space: nowrap; cursor: pointer;
}
.tc-range[aria-pressed="true"] { background: var(--brand-soft); border-color: var(--brand); color: var(--brand-deep); }

/* rom-utvalg for snittet: serie-etikett + Alle/Ingen over de scroll-bare chipsene */
.tc-roomhead { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.tc-series-label { font-size: 0.9rem; font-weight: 750; color: var(--fg); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tc-roomctl { display: inline-flex; gap: 4px; flex: 0 0 auto; }
.tc-roomctl-btn { min-height: 30px; padding: 0 10px; border: 1px solid var(--border);
  border-radius: 8px; background: transparent; color: var(--muted);
  font: inherit; font-weight: 650; font-size: 0.8rem; cursor: pointer; }
.tc-roomctl-btn:hover { color: var(--fg); }

/* rom-chips (multi-toggle, horisontal scroll-snap) */
.tc-rooms { display: flex; gap: 8px; overflow-x: auto; scroll-snap-type: x proximity;
  padding-bottom: 4px; margin-bottom: 10px; -webkit-overflow-scrolling: touch; }
.tc-rooms::-webkit-scrollbar { height: 0; }
.tc-room {
  flex: 0 0 auto; scroll-snap-align: start; min-height: 36px; padding: 0 14px;
  border: 1px solid var(--border); border-radius: 999px; background: var(--card-bg);
  color: var(--muted); font: inherit; font-weight: 650; font-size: 0.88rem; cursor: pointer; white-space: nowrap;
  opacity: .55; transition: opacity .12s;
}
.tc-room[aria-pressed="true"] { background: var(--brand-soft); border-color: var(--brand);
  color: var(--brand-deep); opacity: 1; }
/* iOS: fjern den grå tap-highlighten + double-tap-delay som ga en «rar farge»
   ved tap. Fokus-ring kun for tastatur (ikke stuck etter et tapp). */
.act-tab, .tc-range, .tc-room, .tc-roomctl-btn {
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.tc-room:focus:not(:focus-visible), .tc-range:focus:not(:focus-visible) { outline: none; }
.tc-room:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }

/* selve grafen */
.tempchart { position: relative; width: 100%; max-width: 560px; margin: 0 auto; }
.tempchart svg { display: block; width: 100%; height: auto; touch-action: none; }
.tc-grid { stroke: var(--border); stroke-width: 1; vector-effect: non-scaling-stroke; }
.tc-axis-label { fill: var(--muted); font-size: 9px; font-weight: 600; }
.tc-set-area { fill: var(--brand); opacity: .10; }
.tc-set-line { fill: none; stroke: var(--brand); stroke-width: 2; stroke-linejoin: round;
  stroke-linecap: round; vector-effect: non-scaling-stroke; }
/* program-settpunkt = lilla, litt tynnere/stiplet så det skiller seg fra manuell */
.tc-prog-line { fill: none; stroke: var(--prog); stroke-width: 2; stroke-dasharray: 5 3;
  stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.tc-meas-dot { fill: var(--frost-text); stroke: var(--card-bg); stroke-width: 1; }
/* kollapset klynge: vertikal min–maks-strek = ÆRLIG spredning under ett besøk */
.tc-meas-spread { stroke: var(--frost-text); stroke-width: 2; opacity: .45;
  stroke-linecap: round; vector-effect: non-scaling-stroke; }
/* satt-endekapsel (rund prikk + tall) så «hva holder vi nå» leses raskt */
.tc-endcap { stroke: var(--card-bg); stroke-width: 1.5; }
.tc-endcap--set { fill: var(--brand); }
/* siste MÅLING = hul ring («nå»-ankeret, eneste hule glyf — ingen SVG-tekst;
   verdien står i legenden). MÅ stå ETTER .tc-endcap (lik spesifisitet —
   kildeorden avgjør stroke-overstyringen). */
.tc-endcap--meas { fill: var(--card-bg); stroke: var(--frost-text); stroke-width: 2; }
.tc-endcap-label { font-size: 10px; font-weight: 800; }
.tc-endcap-label--set { fill: var(--brand-deep); }
/* linja er FIGUREN (var spøkelse 1.4/.55 — usynlig); fortsatt lettere enn
   satt-linjas 2px rust så hierarkiet består */
.tc-meas-line { fill: none; stroke: var(--frost-text); stroke-width: 1.8; opacity: .8;
  stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.tc-cursor { stroke: var(--muted); stroke-width: 1; vector-effect: non-scaling-stroke; opacity: .6; }
.tc-cursor-dot { fill: var(--brand); stroke: var(--card-bg); stroke-width: 1.5; }

/* tooltip (posisjoneres via element.style — CSSOM, tillatt) */
/* Boks-posisjonert (JS setter left/top = boksens KANTER, ingen translate) så den
   ALDRI kan flyte utenfor grafen/viewporten — verken venstre eller høyre. */
.tc-tip {
  position: absolute; pointer-events: none; z-index: 5;
  max-width: calc(100% - 12px); box-sizing: border-box; /* aldri bredere enn grafen → aldri klippet i sidene */
  background: var(--card-bg); border: 1px solid var(--border); border-radius: 9px;
  padding: 6px 9px; font-size: 0.78rem; font-weight: 600; color: var(--fg);
  box-shadow: 0 4px 14px rgba(0,0,0,.14);
  white-space: normal; text-align: center; line-height: 1.35; /* wrap mellom felt på smal skjerm */
  opacity: 0; transition: opacity .1s;
}
.tc-tip.is-on { opacity: 1; }
/* hvert felt holdes samlet; linjebrudd skjer kun i « · »-mellomrommene */
.tc-tip > b, .tc-tip > span { white-space: nowrap; }
.tc-tip b { font-weight: 800; }
.tc-tip .tc-tip-set { color: var(--brand-deep); }
.tc-tip .tc-tip-meas { color: var(--frost-text); }
.tc-tip .tc-tip-rooms { color: var(--muted); font-weight: 600; }

/* forklaring + tom-/feil-tekst */
.tc-legend { display: flex; gap: 16px; justify-content: center; margin-top: 10px;
  font-size: 0.8rem; font-weight: 650; color: var(--muted); }
.tc-leg { display: inline-flex; align-items: center; gap: 6px; }
/* strek for linjene (satt/program), rund prikk for de MÅLTE punktene */
.tc-leg::before { content: ""; width: 14px; height: 3px; border-radius: 2px; background: currentColor; }
.tc-leg--set { color: var(--brand-deep); }
.tc-leg--prog { color: var(--prog); }
.tc-leg--meas { color: var(--frost-text); }
.tc-leg--meas::before { width: 10px; height: 10px; border-radius: 50%; }
.tc-note { margin: 14px auto 0; max-width: 520px; text-align: center; color: var(--muted);
  font-size: 0.9rem; line-height: 1.4; }
.tc-note .tc-retry { margin-left: 6px; background: none; border: 0; color: var(--brand-deep);
  font: inherit; font-weight: 700; cursor: pointer; text-decoration: underline; }

@media (prefers-reduced-motion: reduce) {
  .act-tab, .tc-tip { transition: none; }
}
