/* ============================================================
   DaysOff — base design system
   Light, airy, holiday/vacation vibe. Mobile-first.
   ============================================================ */

:root {
    /* Palette — sky & sea blue, warm sand, soft green accent */
    --sky:        #eaf6fb;   /* page background, top */
    --sky-2:      #f7fbfd;   /* page background, bottom */
    --sea:        #2b8fbf;   /* primary */
    --sea-deep:   #1d6f97;   /* primary hover */
    --sand:       #fbf3e4;   /* warm surface */
    --sun:        #ffce5c;   /* highlight / saldo */
    --leaf:       #5bb98b;   /* success / accent */
    --coral:      #ff7a66;   /* alert / danger */

    --ink:        #1f2d3a;   /* primary text */
    --ink-soft:   #51606d;   /* secondary text */
    --ink-faint:  #63707c;   /* tertiary text; lightest value that still clears 4.5:1 on --sky */
    --line:       #e3edf2;   /* hairlines / borders */
    --surface:    #ffffff;   /* cards */
    /* Surfaces. Named by job, not by colour, because every one of them stops being white in
       dark mode, and a rule that says #fff there is a bug waiting for a dark screen. */
    --surface-2:      #ffffff;              /* the foot of the page gradient */
    --surface-soft:   rgba(255,255,255,.7); /* icon buttons sitting on the glass header */
    --surface-veil:   rgba(255,255,255,.72);/* the header itself */
    --surface-veil-2: rgba(255,255,255,.6); /* the footer */

    /* Status families. A tint, an ink and a hairline belong together: change one alone in dark
       mode and a badge turns into pale text on a pale ground. They flip as a set or not at all. */
    --ok-bg:   #edf9f2;  --ok-ink:   #2f7d57;  --ok-line:   #cdeede;
    --warn-bg: #fff4d6;  --warn-ink: #856a17;  --warn-line: #f0d98a;
    --err-bg:  #fff0ec;  --err-ink:  #b23b28;  --err-line:  #ffd6cc;
    --info-bg: #eaf1ff;  --info-ink: #2c4a8f;
    --mute-bg: #f1f3f5;  --mute-ink: #616c76;
    --pending-bg: #fff6dd; --pending-ink: #7a5a09;
    --saldo-1: #fff6dd;  --saldo-2: var(--sun); --saldo-ink: #7a5a09;
    --placeholder: #d6ecf5; --placeholder-ink: #517f95;  /* where a photo is missing */
    --sea-tint: rgba(43,143,191,.10);
    --on-primary: #ffffff;   /* text and icons ON the brand fill */
    /* --sea does two jobs that pull opposite ways: it is the accent on hairlines, focus rings
       and hovers, where lighter reads better, and it is the FILL under --on-primary, where
       lighter fails contrast. One value cannot serve both, so the fill gets its own token.
       White on the old --sea was 3.63:1. */
    --primary:    #217aa5;
    --skeleton:    #e4eff5;   /* loading placeholders, and the lighter band that sweeps them */
    --skeleton-hi: #f6fbfd;
    --loader-sun:  #eea020;   /* a warmer gold than --sun, which is lost on white */

    /* Spacing scale */
    --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
    --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px;

    /* Layer scale. Never write a bare z-index anywhere else: two files that disagree about a
       number is how a control ends up drawn behind an opaque surface and looks broken, with
       nothing in the markup to explain why. The order is the argument. A map sits in the page,
       a sticky header floats over it, a menu belongs to a control, an overlay covers the page,
       and a dialog is what that overlay exists to show. */
    --layer-map:     1;      /* Leaflet's own canvas, kept at the bottom on purpose */
    --layer-raised:  2;      /* a control lifted just off its own container */
    --layer-sticky:  50;     /* the site header, which follows the scroll */
    --layer-float:   300;    /* a panel anchored to a control: the help panel */
    --layer-onmap:   500;    /* a button sitting on top of the map */
    --layer-overlay: 1000;   /* something laid over the whole page */
    --layer-dialog:  1100;   /* what that overlay exists to show */

    --radius:    14px;
    --radius-lg: 22px;
    --radius-pill: 999px;

    --shadow-sm: 0 1px 2px rgba(31,45,58,.06), 0 2px 8px rgba(31,45,58,.05);
    --shadow-md: 0 6px 18px rgba(29,111,151,.10), 0 2px 6px rgba(31,45,58,.06);
    --shadow-lg: 0 18px 50px rgba(29,111,151,.16);

    --font: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
    --maxw: 1120px;
}

/* ---------- Dark theme ----------
   One button in the header switches it. The default follows the operating system, and an explicit
   choice wins and is remembered; the resolving happens in the inline head script, so the page is
   never painted in the wrong theme first. Everything below is tokens only. No rule in any
   stylesheet may name a colour of its own, or it survives the switch and looks broken.

   Deliberately NOT also written as a prefers-color-scheme block: that means two copies of this
   palette to keep in step forever, and the copy nobody edits is the one that rots. The price is
   that a browser with script off stays light, which is the page we already shipped. */
:root { color-scheme: light; }
:root[data-theme="dark"] {
    /* Deep sea navy, not neutral grey. The light theme is sky and sea, so the dark one is the same
       water after dark: every ground keeps the blue hue and only the lightness drops. */
    --sky:        #0a2033;   /* top of the page gradient */
    --sky-2:      #0c2639;
    --surface-2:  #07192a;   /* its foot, the deepest point */
    --surface:    #11304a;   /* cards, lifted clearly above the ground */
    --sand:       #163a5b;   /* the warm surface becomes a lifted blue; it is a hover ground */
    --line:       #1d4260;
    /* The blues go UP, not down. "Deep" means prominent, and on a dark ground prominence is
       lightness: light mode #1d6f97 on #11304a is about 2:1 and cannot be read. */
    --sea:        #4fb8e6;
    --sea-deep:   #8ad4f2;
    --sun:        #ffce5c;
    --leaf:       #63c795;
    --coral:      #ff9280;

    --ink:        #e9f2f8;
    --ink-soft:   #aec6d8;
    --ink-faint:  #8aa9bf;   /* lifted from the light-mode faint, which lands under 4.5:1 here */
    --surface-soft:   rgba(255,255,255,.07);
    --surface-veil:   rgba(8,28,45,.80);
    --surface-veil-2: rgba(8,28,45,.55);

    --ok-bg:   #0f3326;  --ok-ink:   #7ddfae;  --ok-line:   #1c5138;
    --warn-bg: #3a2d0e;  --warn-ink: #f5cf7c;  --warn-line: #5f4a1c;
    --err-bg:  #40201b;  --err-ink:  #ff9f8e;  --err-line:  #61312a;
    --info-bg: #16274f;  --info-ink: #b3c6ff;
    --mute-bg: #18304a;  --mute-ink: #9db4c6;
    --pending-bg: #3a2d0e; --pending-ink: #f5cf7c;
    /* The balance pill keeps its warm colour, which is what makes it findable, but bright gold on
       a dark header is a headlight. Muted body, warm text. */
    --saldo-1: #5f4d14;  --saldo-2: #8f7119;  --saldo-ink: #ffe3ab;
    --placeholder: #11304a; --placeholder-ink: #5a90b5;   /* clears 3:1 as a graphic */
    --sea-tint: rgba(79,184,230,.16);
    --on-primary: #06202f;   /* dark ink on the lifted blue; white there is about 1.6:1 */
    --primary:    #4fb8e6;
    --skeleton:    #173a57;   /* lifted off the card surface, or the placeholders vanish */
    --skeleton-hi: #235277;
    --loader-sun:  #ffce5c;

    /* A shadow is drawn by contrast with its ground. One tuned for white is invisible here, and
       the cards would float with no edge at all. */
    --shadow-sm: 0 1px 2px rgba(0,0,0,.45), 0 2px 8px rgba(0,0,0,.30);
    --shadow-md: 0 6px 18px rgba(0,0,0,.45), 0 2px 6px rgba(0,0,0,.30);
    --shadow-lg: 0 18px 50px rgba(0,0,0,.55);

    color-scheme: dark;   /* native selects, scrollbars and the date picker follow too */
}

* { box-sizing: border-box; }

/* One multiplier for the whole page. Every font-size here is rem or clamp, so this moves all
   type at once. Spacing stays in px on purpose: the text grows inside the boxes rather than the
   whole layout scaling, which is what lets someone fit more rows on a screen at 80 %. */
html { font-size: calc(16px * var(--text-scale, 1)); }
html, body { height: 100%; }

body {
    margin: 0;
    font-family: var(--font);
    color: var(--ink);
    background: linear-gradient(180deg, var(--sky) 0%, var(--sky-2) 38%, var(--surface-2) 100%);
    background-attachment: fixed;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    display: flex;
    flex-direction: column;
}

h1, h2, h3 { line-height: 1.2; margin: 0 0 var(--sp-3); font-weight: 700; letter-spacing: -.01em; }
h1 { font-size: clamp(1.8rem, 1.2rem + 2.4vw, 2.7rem); }
h2 { font-size: clamp(1.35rem, 1.1rem + 1vw, 1.8rem); }
p  { margin: 0 0 var(--sp-4); color: var(--ink-soft); }

a { color: var(--sea-deep); text-decoration: none; }
a:hover { text-decoration: underline; }

.container { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 var(--sp-5); }

.site-main { flex: 1 0 auto; }

/* ---------- Header ---------- */
.preview-banner { background: var(--warn-bg); color: var(--warn-ink); text-align: center; padding: 8px 16px; font-size: .86rem; font-weight: 600; border-bottom: 1px solid var(--warn-line); }
.site-header {
    position: sticky; top: 0; z-index: var(--layer-sticky);
    background: var(--surface-veil);
    backdrop-filter: saturate(160%) blur(12px);
    border-bottom: 1px solid var(--line);
}
.site-header__inner { display: flex; align-items: center; gap: var(--sp-5); height: 64px; }
.brand { display: inline-flex; align-items: center; gap: var(--sp-2); font-weight: 800; font-size: 1.15rem; color: var(--ink); }
.brand:hover { text-decoration: none; }
.brand__mark { font-size: 1.3rem; }
.brand__logo { height: 30px; width: auto; display: block; }
/* Company logos are arbitrary aspect ratios (mostly wide jpg/png). Cap the width and let the
   image scale to fit inside the 30px height without distortion or blowing out the header on mobile. */
.brand__logo--company { max-width: 170px; object-fit: contain; }
@media (max-width: 560px){ .brand__logo--company { max-width: 128px; } }
.site-nav { display: none; }
.site-nav a { color: var(--ink-soft); font-weight: 600; }
.site-nav a:hover { color: var(--sea-deep); text-decoration: none; }
.site-nav__saldo { display: none; }   /* shown in the mobile dropdown only */
/* The other language: in the menu for a member, in the bar itself before signing in. A globe and the
   language's own name, never a flag. */
.site-nav__lang, .lang-switch { display: inline-flex; align-items: center; gap: 6px; }
.site-nav__lang svg, .lang-switch svg { width: 1.05em; height: 1.05em; flex: none; }
.lang-switch { margin-left: auto; padding: 8px 10px; border-radius: var(--radius); color: var(--ink-soft); font-weight: 600; }
.lang-switch:hover { color: var(--sea-deep); background: var(--surface); text-decoration: none; }
.site-nav.is-open a.site-nav__lang { display: flex; }

/* Hamburger button (mobile only) */
.nav-toggle { display: none; flex-direction: column; justify-content: center; gap: 4px; width: 40px; height: 40px; padding: 0 9px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); cursor: pointer; }
.nav-toggle__bar { display: block; width: 100%; height: 2px; background: var(--ink); border-radius: 2px; transition: transform .2s ease, opacity .2s ease; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.saldo-chip {
    display: inline-flex; align-items: center; gap: var(--sp-2);
    background: linear-gradient(180deg, var(--saldo-1), var(--saldo-2));
    color: var(--saldo-ink); font-weight: 700; font-size: .85rem;
    padding: 6px 12px; border-radius: var(--radius-pill); box-shadow: var(--shadow-sm);
}
.saldo-chip__label { opacity: .8; font-weight: 600; }

/* ---------- Header tools (the member's own controls) ----------
   One cluster, read left to right: what there is to spend, the two controls that change how the
   page looks, and the way out. The hairline marks the real boundary, between information and
   controls. Shown signed in only: an anonymous sign-out button is a puzzle, and a visitor on the
   login page has no balance to read. */
.header-tools { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.header-tools__sep { width: 1px; height: 24px; margin: 0 4px; background: var(--line); }
.menu-wrap { position: relative; display: inline-flex; }

/* 44px square is the floor for a finger, and it is the same floor the calendar arrows were
   raised to. Keep it on desktop too: the cost is a few pixels, the benefit is nobody misses. */
.icon-button {
    display: inline-grid; place-items: center;
    width: 44px; height: 44px; padding: 0;
    font: inherit; font-weight: 800; font-size: 1rem;
    background: var(--surface-soft); color: var(--ink-soft);
    border: 1px solid var(--line); border-radius: var(--radius);
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
}
@media (hover: hover) { .icon-button:hover { border-color: var(--sea); color: var(--sea-deep); } }
.icon-button:focus-visible { outline: 2px solid var(--sea); outline-offset: 2px; }
.icon-button[aria-expanded="true"] { border-color: var(--sea); color: var(--sea-deep); }
.icon-button svg { display: block; width: 20px; height: 20px; }
/* The icon says where the button takes you: a moon while the page is light, a sun while it is
   dark. Both sit in the markup and one is hidden, which is steadier than swapping paths from
   script and cannot show the wrong one in the moment before app.js runs. */
#theme-button .icon-sun { display: none; }
:root[data-theme="dark"] #theme-button .icon-sun  { display: block; }
:root[data-theme="dark"] #theme-button .icon-moon { display: none; }

.size-menu {
    position: absolute; right: 0; top: calc(100% + 6px); z-index: var(--layer-float);
    display: flex; flex-direction: column; gap: 2px;
    min-width: 108px; padding: var(--sp-2);
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}
/* `hidden` loses to any display rule, and this menu is flex, so it has to be said explicitly. */
.size-menu[hidden] { display: none; }
.size-menu button {
    font: inherit; font-weight: 700; text-align: left;
    padding: 9px 12px; min-height: 40px;
    background: none; border: 0; border-radius: var(--radius);
    color: var(--ink-soft); cursor: pointer;
}
.size-menu button:hover { background: var(--sand); }
.size-menu button[aria-checked="true"] { background: var(--sea-tint); color: var(--sea-deep); }
.size-menu button[data-size="80"]  { font-size: .8rem; }
.size-menu button[data-size="90"]  { font-size: .9rem; }
.size-menu button[data-size="115"] { font-size: 1.15rem; }
.size-menu button[data-size="130"] { font-size: 1.3rem; }

/* The sign-out form must not take part in the flex row, or its button is spaced differently from
   everything beside it and nobody can say why. */
.logout-form { display: contents; }
/* A button that has to look like the link it replaced. It became a form because a GET link can be
   fetched by a prefetcher, a scanner or an image tag on another site, and sign the member out
   without them touching anything. */
.linkish { background: none; border: 0; padding: 0; font: inherit; color: var(--sea-deep); cursor: pointer; }
.linkish:hover { text-decoration: underline; }

/* ---------- Buttons ---------- */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
    font: inherit; font-weight: 700; cursor: pointer;
    padding: 13px 22px; border-radius: var(--radius-pill); border: 1px solid transparent;
    transition: transform .08s ease, box-shadow .2s ease, background .2s ease;
    text-decoration: none; white-space: nowrap;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn--primary { background: linear-gradient(180deg, var(--primary), var(--sea-deep)); color: var(--on-primary); box-shadow: var(--shadow-md); }
@media (hover: hover) { .btn--primary:hover { background: var(--sea-deep); } }
.btn--ghost { background: var(--surface-soft); color: var(--ink); border-color: var(--line); }
@media (hover: hover) { .btn--ghost:hover { background: var(--surface); } }
.btn--sm { padding: 8px 14px; font-size: .9rem; }
.btn--block { width: 100%; }
.btn[disabled] { opacity: .55; cursor: not-allowed; }

/* ---------- Cards ---------- */
.card {
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--radius-lg); box-shadow: var(--shadow-md); padding: var(--sp-6);
}

/* ---------- Forms ---------- */
.field { margin-bottom: var(--sp-4); }
.field label { display: block; font-weight: 600; font-size: .9rem; margin-bottom: 6px; color: var(--ink); }
.input {
    width: 100%; font: inherit; color: var(--ink);
    padding: 13px 15px; border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--surface); transition: border-color .15s ease, box-shadow .15s ease;
}
.input:focus { outline: none; border-color: var(--sea); box-shadow: 0 0 0 4px rgba(43,143,191,.15); }
.input::placeholder { color: var(--ink-faint); }

/* ---------- Notices ---------- */
.notice { padding: 12px 16px; border-radius: var(--radius); font-size: .92rem; font-weight: 600; }
.notice--error { background: var(--err-bg); color: var(--err-ink); border: 1px solid var(--err-line); }
.notice--ok    { background: var(--ok-bg); color: var(--ok-ink); border: 1px solid var(--ok-line); }
.is-hidden { display: none !important; }

/* ---------- Footer ---------- */
.site-footer { flex-shrink: 0; margin-top: var(--sp-8); border-top: 1px solid var(--line); background: var(--surface-veil-2); }
.site-footer__inner { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4); padding-top: var(--sp-5); padding-bottom: var(--sp-5); }
.site-footer__brand { font-weight: 800; margin: 0; }
.site-footer__logo { height: 26px; width: auto; display: block; opacity: .85; }
.site-footer__links { display: flex; gap: var(--sp-5); margin-left: auto; }
.site-footer__links a { color: var(--ink-soft); font-size: .9rem; }
.site-footer__copy { width: 100%; margin: 0; color: var(--ink-faint); font-size: .82rem; }

/* ---------- Utilities ---------- */
.stack > * + * { margin-top: var(--sp-4); }
.text-center { text-align: center; }
.muted { color: var(--ink-soft); }

/* ---------- Member deals strip (home): the partner cards roll to the right ----------
   Delivered as a widget on 06.10.2026 and kept as it came: 67.5 px tall, 48 x 44 px images, the
   partners' own colours, 33.75 px/s, no buttons and no hover pause. The wrapper and the label are
   ours. Someone who has asked for less motion gets the strip still, scrollable by hand. */
.home__deals { margin: 0 0 var(--sp-4); }
.home__deals-label { font-size: .85rem; margin: 0 0 8px; }
.do-ticker, .do-ticker * { box-sizing: border-box; }
.do-ticker {
    --do-card-width: 238px; --do-gap: 4px;
    position: relative; display: block; width: 100%; height: 67.5px; min-height: 67.5px; max-height: 67.5px;
    margin: 0; padding: 0; border: 0; border-radius: var(--radius); overflow-x: auto; overflow-y: hidden;
    scrollbar-width: none; scroll-behavior: auto; overflow-anchor: none; direction: ltr; text-align: left;
    font-family: Arial, Helvetica, sans-serif; background: transparent; box-shadow: var(--shadow-sm);
    opacity: .89;   /* a little paler than the partners' own colours, to sit with the page (Tom, 07.10.2026) */
}
/* Full strength while a card has the keyboard, so the focus outline and the text read clearly. */
.do-ticker:focus-within { opacity: 1; }
.do-ticker::-webkit-scrollbar { display: none; }
.do-ticker[data-ready="true"] { overflow: hidden; touch-action: pan-y pinch-zoom; }
.do-ticker__track { display: flex; width: max-content; height: 67.5px; margin: 0; padding: 0; will-change: transform; }
.do-ticker__group { display: flex; flex: 0 0 auto; align-items: stretch; gap: var(--do-gap); width: max-content; height: 67.5px; margin: 0; padding: 0 var(--do-gap) 0 0; list-style: none; }
.do-ticker__group > li { display: block; flex: 0 0 var(--do-card-width); width: var(--do-card-width); height: 67.5px; margin: 0; padding: 0; }
.do-ticker .do-ticker__card {
    display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; align-items: center; column-gap: 6px;
    width: 100%; height: 67.5px; margin: 0; padding: 5px 8px; border: 0; border-radius: 0;
    background: var(--offer-bg); color: var(--offer-fg); text-decoration: none; cursor: pointer;
}
.do-ticker__media { position: relative; display: grid; place-items: center; width: 48px; height: 44px; overflow: hidden; border-radius: 3px; background: var(--image-bg, #19382e); color: var(--image-fg, #ffffff); }
.do-ticker__image { position: absolute; inset: 0; display: block; width: 48px; height: 44px; margin: 0; padding: 0; border: 0; object-fit: cover; object-position: var(--image-position, 50% 50%); }
.do-ticker__media[data-image-kind="logo"] .do-ticker__image { object-fit: contain; }
.do-ticker__partner, .do-ticker__benefit { display: flex; flex-direction: column; min-width: 0; }
.do-ticker__partner { gap: 3px; }
.do-ticker__name { font-size: 14px; font-weight: 700; line-height: 1.08; letter-spacing: -0.3px; }
.do-ticker__description { font-size: 10px; font-weight: 400; line-height: 1.2; }
.do-ticker__benefit { align-items: flex-end; gap: 3px; text-align: right; white-space: nowrap; }
.do-ticker__prefix, .do-ticker__label { font-size: 10px; font-weight: 400; line-height: 1.1; }
.do-ticker__value { font-size: 21px; font-weight: 800; line-height: 1; letter-spacing: -0.5px; }
.do-ticker__card:focus-visible { outline: 2px solid var(--offer-fg); outline-offset: -4px; text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 480px) { .do-ticker { --do-card-width: 228px; } }
@media (prefers-reduced-motion: reduce) { .do-ticker[data-ready="true"] { overflow-x: auto; } }

/* ---------- Member deals page (/fordeler): every deal in full ----------
   As the public page on daysoff.no was laid out: a large picture beside a text panel, the sides
   alternating down the page, and the benefit as a badge on the picture in the partner's colours. */
.deals__lead { font-size: clamp(1.35rem, 1rem + 1.6vw, 2rem); font-weight: 700; line-height: 1.25; margin: 0 0 var(--sp-3); letter-spacing: -.01em; }
.deals__lead em { font-style: italic; color: var(--sea-deep); }
.deals__intro { max-width: 62ch; }
.deals__list { display: grid; gap: var(--sp-6); margin-top: var(--sp-6); }
.deal { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-5); align-items: start; scroll-margin-top: 90px; }
.deal:nth-child(even) .deal__media { order: 2; }
.deal__media { position: relative; aspect-ratio: 16 / 10; border-radius: var(--radius-lg); overflow: hidden; background: var(--image-bg, #19382e); box-shadow: var(--shadow-md); }
.deal__media img { position: absolute; inset: 0; width: 100%; height: 100%; display: block; object-fit: cover; object-position: var(--image-position, 50% 50%); }
/* A logo is shown whole on its own colour; a photo fills the frame. */
.deal__media--logo img { object-fit: contain; }
.deal__badge { position: absolute; left: 16px; bottom: 16px; display: inline-flex; flex-direction: column; align-items: flex-start; gap: 1px; padding: 10px 16px; border-radius: var(--radius); background: var(--offer-bg); color: var(--offer-fg); font-size: 1.5rem; font-weight: 800; line-height: 1; letter-spacing: -.5px; box-shadow: var(--shadow-sm); }
.deal__badge small { font-size: .72rem; font-weight: 600; letter-spacing: 0; }
.deal__text { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); padding: var(--sp-6); }
.deal__text h2 { margin: 0 0 4px; font-size: 1.4rem; }
.deal__short { margin: 0 0 14px; color: var(--ink-soft); font-weight: 600; }
.deal__text p { margin: 0 0 10px; font-size: .95rem; }
.deal__code { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
.deal__code code { font-size: 1.05rem; font-weight: 700; letter-spacing: .5px; background: var(--sea-tint); color: var(--sea-deep); padding: 5px 12px; border-radius: 8px; user-select: all; }
.deal__go { margin: 16px 0 0; }
.deals__foot { margin-top: var(--sp-6); }
@media (max-width: 720px) {
    .deal { grid-template-columns: 1fr; gap: var(--sp-3); }
    .deal:nth-child(even) .deal__media { order: 0; }
    .deal__media { aspect-ratio: 16 / 9; }
}

/* ---------- Responsive ---------- */
@media (min-width: 760px) {
    .site-nav { display: flex; gap: var(--sp-5); margin-left: var(--sp-3); }
}
@media (max-width: 759px) {
    /* Mobile: the hamburger reveals the nav links as a dropdown. The tools cluster stays in
       the bar at every width. */
    .nav-toggle { display: inline-flex; }
    .saldo-chip__label { display: none; }   /* the pill shape already says what it is */
    .site-nav.is-open {
        display: flex; flex-direction: column; gap: 2px;
        position: absolute; top: calc(100% + 6px); right: var(--sp-5); min-width: 210px; z-index: var(--layer-float);
        background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
        box-shadow: var(--shadow-lg); padding: var(--sp-3);
    }
    .site-nav.is-open a, .site-nav.is-open .site-nav__saldo { display: block; padding: 10px 12px; border-radius: var(--radius); }
    .site-nav.is-open a:hover { background: var(--sand); }
    .site-nav.is-open .site-nav__saldo { color: var(--ink-faint); border-top: 1px solid var(--line); margin-top: 4px; padding-top: 12px; }
    /* The chip in the bar is already showing it. Must come after the display: block above,
       which has the same weight and would otherwise win on being later. */
    .site-nav.is-open .site-nav__saldo { display: none; }
}

@media (max-width: 560px) {
    /* A company logo, a balance pill and three controls do not fit beside each other on a phone.
       The pill is the one thing that is also somewhere else, so it goes and the menu shows the
       balance again. The controls stay: this is the width they matter most at. */
    .saldo-chip { display: none; }
    .site-nav.is-open .site-nav__saldo { display: block; }
    .header-tools { gap: 2px; }
    /* Four controls plus a hamburger: the row only fits if the logo and the gaps give way. */
    .site-header__inner { gap: var(--sp-2); }
    .brand__logo--company { max-width: 104px; }
    .header-tools__sep { display: none; }
    .header-tools .icon-button { width: 40px; height: 40px; }
}
/* Footer "Tips oss" trigger — styled like a footer link */
.site-footer__link-btn { background: none; border: 0; padding: 0; font: inherit; font-size: .9rem; color: var(--ink-soft); cursor: pointer; }
.site-footer__link-btn:hover { text-decoration: underline; color: var(--ink); }

/* Tip-us modal (global; opened by any .js-tip-open trigger) */
body.no-scroll { overflow: hidden; }
.tip-modal, .help-modal { position: fixed; inset: 0; z-index: var(--layer-overlay); display: flex; align-items: center; justify-content: center; padding: var(--sp-4); background: rgba(8, 22, 32, .55); }
.tip-modal[hidden], .help-modal[hidden] { display: none !important; }
.tip-modal__card { position: relative; width: 100%; max-width: 460px; padding: var(--sp-6); }
.tip-modal__card h2 { margin: 0 0 4px; }
.tip-modal__close { position: absolute; top: 10px; right: 12px; width: 36px; height: 36px; border: 0; background: none; font-size: 1.6rem; line-height: 1; color: var(--ink-soft); cursor: pointer; border-radius: 50%; }
@media (hover: hover) { .tip-modal__close:hover { background: var(--sand); } }
.tip-field { display: block; margin: var(--sp-4) 0; }
.tip-field > span { display: block; margin-bottom: 6px; font-weight: 600; font-size: .9rem; }
.tip-field small { color: var(--ink-faint); font-weight: 400; }
.tip-field textarea.input { resize: vertical; min-height: 90px; }
.tip-modal__actions { display: flex; justify-content: flex-end; gap: var(--sp-2); margin-top: var(--sp-4); }
.tip-modal__status { margin: var(--sp-3) 0 0; padding: 10px 14px; border-radius: var(--radius); font-size: .9rem; }
.tip-modal__status.is-ok  { background: var(--ok-bg); color: var(--ok-ink); }
.tip-modal__status.is-err { background: var(--err-bg); color: var(--err-ink); }

/* ---------- Help panel (the "?" in the header) ---------- */
/* Taller than the tip form and it holds real prose, so the card scrolls rather than the page
   behind it. dvh first fails on old engines and falls back to the vh line above it. */
.help-modal__card { position: relative; width: 100%; max-width: 560px; padding: var(--sp-6); }
.help-modal__card { max-height: calc(100vh - 2 * var(--sp-4)); }
.help-modal__card { max-height: calc(100dvh - 2 * var(--sp-4)); overflow-y: auto; }
.help-modal__card h2 { margin: 0 0 4px; }
.help-modal__lead { margin-bottom: var(--sp-4); }
.help-modal__foot { margin: var(--sp-4) 0 0; font-size: .88rem; }

.faq { display: flex; flex-direction: column; }
.faq__q {
    display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
    width: 100%; text-align: left; font: inherit; font-weight: 700; font-size: .96rem;
    padding: 12px 14px; min-height: 48px;   /* a finger, not a mouse pointer */
    background: none; border: 0; border-top: 1px solid var(--line); border-radius: 0;
    color: var(--ink); cursor: pointer;
}
.faq__q:first-of-type { border-top: 0; }
@media (hover: hover) { .faq__q:hover { color: var(--sea-deep); } }
.faq__q:focus-visible { outline: 2px solid var(--sea); outline-offset: -2px; }
/* The sign is generated, not written in the markup, so it can never disagree with the state
   the button reports to a screen reader. */
.faq__q::after { content: "+"; font-size: 1.25rem; line-height: 1; color: var(--ink-faint); }
.faq__q[aria-expanded="true"] { color: var(--sea-deep); }
.faq__q[aria-expanded="true"]::after { content: "\2212"; color: var(--sea-deep); }
/* Same element as the inline help panels, so it keeps their show/hide behaviour, but inside
   a dialog the warm tint on nine stacked answers is too much. */
.help-panel.faq__a { margin: 0; padding: 0 14px var(--sp-4); background: none; border: 0; border-radius: 0; }
.faq__a ul { margin: 0 0 var(--sp-2); padding-left: 20px; }
.faq__a li { margin-bottom: 5px; }

/* ---------- Loading ---------- */
/* A sun that turns while a page fetches. It is decoration: the words beside it carry the
   meaning, and the element holding both is a status region, so a screen reader hears them. */
.loader { display: inline-flex; align-items: center; gap: var(--sp-3); color: var(--ink-soft); font-weight: 600; }
.loader__sun { width: 30px; height: 30px; flex: none; color: var(--loader-sun); animation: loader-turn 7s linear infinite; }
@keyframes loader-turn { to { transform: rotate(360deg); } }

/* Placeholders shaped like what is coming. Only a light band moves across them, so the boxes
   themselves stay put and nothing reflows when the real content replaces them. */
.skeleton {
    display: block; border-radius: 6px;
    background: linear-gradient(90deg, var(--skeleton) 0%, var(--skeleton-hi) 45%, var(--skeleton) 90%);
    background-size: 220% 100%;
    animation: skeleton-sweep 1.5s ease-in-out infinite;
}
@keyframes skeleton-sweep { from { background-position: 120% 0; } to { background-position: -120% 0; } }

/* Someone who has asked for less motion still gets the shapes and the words, just still. */
@media (prefers-reduced-motion: reduce) {
    .loader__sun, .skeleton { animation: none; }
}

/* Location picker: country rows are selectable "whole country" options, shown bold above their places */
option.opt-country { font-weight: 700; }

/* Styled confirm dialog (DaysOff.confirm — replaces native confirm) */
.confirm-modal { position: fixed; inset: 0; z-index: var(--layer-dialog); display: flex; align-items: center; justify-content: center; padding: var(--sp-4); background: rgba(8, 22, 32, .55); }
.confirm-modal__card { width: 100%; max-width: 400px; padding: var(--sp-6); }
.confirm-modal__title { margin: 0 0 var(--sp-2); }
.confirm-modal__msg { margin: 0 0 var(--sp-5); color: var(--ink-soft); }
.confirm-modal__actions { display: flex; justify-content: flex-end; gap: var(--sp-2); flex-wrap: wrap; }
.btn--danger { background: #d33030; color: #fff; box-shadow: var(--shadow-md); }
@media (hover: hover) { .btn--danger:hover { background: #b71f1f; } }

/* Help toggles: a "?" beside a heading that reveals a short explanation.
   Delegated in app.js — any page can use .help-toggle + .help-panel with no extra wiring.
   Raised to the top of the line and given the warm highlight colour so it reads as an
   affordance next to a heading rather than punctuation inside it. */
.help-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 18px; height: 18px; margin-left: 7px; padding: 0;
    border: 1px solid var(--warn-line); border-radius: var(--radius-pill);
    background: var(--warn-bg); color: var(--warn-ink);
    font: 700 11px/1 var(--font); cursor: pointer;
    vertical-align: super;            /* sits at the top of the line, not on the baseline */
    position: relative; top: -.1em;
    transition: background .15s ease, border-color .15s ease, color .15s ease;
}
@media (hover: hover) { .help-toggle:hover { background: var(--sun); border-color: #d9b64a; color: #6b5310; } }
.help-toggle:focus-visible { outline: 2px solid var(--sea); outline-offset: 2px; }
.help-toggle[aria-expanded="true"] { background: var(--sun); border-color: #d9b64a; color: #6b5310; }

.help-panel {
    margin: var(--sp-3) 0 var(--sp-4);
    padding: var(--sp-3) var(--sp-4);
    border: 1px solid var(--warn-line); border-radius: var(--radius);
    background: var(--warn-bg); color: var(--ink-soft);
    font-size: .92rem; line-height: 1.6;
}
.help-panel[hidden] { display: none; }
.help-panel p  { margin: 0 0 var(--sp-2); }
.help-panel p:last-child { margin-bottom: 0; }
.help-panel ul { margin: 0 0 var(--sp-2); padding-left: 1.1em; }
.help-panel ul:last-child { margin-bottom: 0; }
.help-panel li { margin: 0 0 3px; }
.help-panel strong { color: var(--ink); }
/* ---- Free-text search ("describe your trip") ------------------------------
   Lives in base.css, not search.css: used on both the home page and /sok.

   Colour discipline: this component stays in the blue/neutral family because its
   controls are ACTIONS (search, remove a filter). Warm yellow is reserved for help
   throughout the site. Two families with one job each, so the page reads as a system
   rather than a set of competing highlights. */
.smart-search { margin-bottom: var(--sp-4); }
.smart-search[hidden] { display: none; }

.smart-search__label {
    display: flex; align-items: center;
    margin-bottom: var(--sp-2);
    font-weight: 600; font-size: .95rem; color: var(--ink);
}
/* The field is a two-line textarea, not an input. Free-text searches are sentences —
   «3 til Polen i høstferien, maks 6200» is 35 characters, and in a single-line field
   the beginning scrolls out of view while you type the end. Two lines show the whole sentence.

   The row is therefore flex-start, not stretch: with stretch the Find button would be
   stretched to the same height as the field. */
.smart-search__row { display: flex; gap: var(--sp-2); align-items: flex-start; }
.smart-search__input {
    flex: 1 1 auto; min-width: 0;
    resize: none;                 /* the drag handle would break the layout */
    line-height: 1.45;
    /* Starts at ONE line and grows with the text (DaysOff.autoGrow). The cap at five
       keeps a pasted paragraph from pushing the button off screen; the field scrolls instead. */
    min-height: calc(1.45em + 26px + 2px);
    max-height: calc(1.45em * 5 + 26px + 2px);
    font-family: inherit;         /* textarea does not inherit the font like input does */
    overflow-y: auto;
}
.smart-search__btn { flex: 0 0 auto; white-space: nowrap; }

.smart-search__note { margin: var(--sp-2) 0 0; color: var(--ink-soft); font-size: .9rem; }
.smart-search__note[hidden] { display: none; }

/* While the model is interpreting. The call takes 1–2 seconds — long enough that a
   static page reads as "nothing happened", so something has to move. The pulse sits on
   the text and a dot in front of it, in the blue family because this is an action in progress. */
.smart-search__note.is-thinking {
    display: flex; align-items: center; gap: var(--sp-2);
    color: var(--sea-deep); font-weight: 600;
}
.smart-search__note.is-thinking::before {
    content: ""; flex: 0 0 auto;
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--sea);
    animation: smart-thinking 1.1s ease-in-out infinite;
}
@keyframes smart-thinking {
    0%, 100% { opacity: 1;  transform: scale(1);   }
    50%      { opacity: .3; transform: scale(.65); }
}

/* The field dims slightly while we work, making it clear the answer applies to the text
   as it stands now — not something the user manages to rewrite in the meantime. */
.smart-search.is-thinking .smart-search__input { opacity: .7; }

/* Respect the system preference: someone who has turned off animations should not get a
   blinking dot. The message still shows, just without motion. */
@media (prefers-reduced-motion: reduce) {
    .smart-search__note.is-thinking::before { animation: none; }
}

/* What we understood — removable, so the interpretation is editable */
.smart-search__chips {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
    margin: var(--sp-3) 0 0; color: var(--ink-faint); font-size: .88rem;
}
.smart-search__chips[hidden] { display: none; }
.smart-chip {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 4px 11px; border: 1px solid var(--line); border-radius: var(--radius-pill);
    background: var(--surface); color: var(--ink);
    font: 600 .86rem/1.5 var(--font); cursor: pointer;
    transition: border-color .15s ease, background .15s ease;
}
@media (hover: hover) { .smart-chip:hover { border-color: var(--sea); background: rgba(43,143,191,.06); } }
.smart-chip:focus-visible { outline: 2px solid var(--sea); outline-offset: 2px; }
.smart-chip span { color: var(--ink-faint); font-weight: 400; }
@media (hover: hover) { .smart-chip:hover span { color: var(--sea-deep); } }

/* "eller velg selv" — a quiet labelled rule between the two ways of searching */
.smart-search__or {
    display: flex; align-items: center; gap: var(--sp-3);
    margin: 0 0 var(--sp-4); color: var(--ink-faint); font-size: 0.92rem;
}
.smart-search__or[hidden] { display: none; }
.smart-search__or::before, .smart-search__or::after {
    content: ""; flex: 1 1 auto; height: 1px; background: var(--line);
}

/* Example queries — dashed so they read as suggestions, not buttons to press */
.smart-search__examples {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
    margin: var(--sp-2) 0 0; color: var(--ink-faint); font-size: .84rem;
}
.smart-example {
    padding: 3px 10px; border: 1px dashed var(--line); border-radius: var(--radius-pill);
    background: transparent; color: var(--ink-soft);
    font: 400 .84rem/1.5 var(--font); cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
}
@media (hover: hover) { .smart-example:hover { border-color: var(--sea); border-style: solid; color: var(--sea-deep); } }
.smart-example:focus-visible { outline: 2px solid var(--sea); outline-offset: 2px; }

/* Mobile. The block had a backslash before the @ — "\@media" — which makes the whole
   at-rule invalid, so nothing in here has worked since 899fcc1. The consequence was the
   free-text field stuck at 143 px next to the Find button on a 375 px screen. */
@media (max-width: 560px) {
    /* The text field gets the full width, and the button drops below. A sentence like
       «romjula, 8 personer med hund» should be typable without the field being half
       the screen. It costs 61 px of height — recovered through shorter example text
       and less padding below. */
    .smart-search__row { flex-direction: column; }
    .smart-search__btn { width: 100%; }

    /* 32 px of padding around the card eats 64 of the 375 available pixels.
       Content matters more than air on small screens. */
    .card { padding: var(--sp-4); }

    /* The examples wrap as before — they should all be visible without sideways
       dragging. Instead the text is shortened in the markup, and the pills tightened
       here, so the four suggestions take fewer lines. */
    .smart-search__examples { gap: 5px; }
    .smart-example { padding: 4px 10px; font-size: .8rem; }

    /* The chips are the receipt for what we understood. A filter beyond the screen edge
       is a filter the user does not know about, so these must not scroll either. */
    .smart-search__chips { gap: 5px; }
    .smart-chip { padding: 4px 9px; font-size: .82rem; }

    /* Phones: 24 px of side margin on a 375 px screen is air the content needs. 12 px keeps
       cards off the glass edge; media that wants the whole width uses .full-bleed. */
    .container { padding: 0 var(--sp-3); }
    .full-bleed { margin-left: calc(-1 * var(--sp-3)); margin-right: calc(-1 * var(--sp-3)); border-radius: 0; border-left: 0; border-right: 0; }
}
