/* Odd Fellow bokning, "Folkets hus" in garnet and gold. Stone ground with
   white rounded tiles, Jost for display, Inter for text, pill buttons. Garnet means decided (buttons,
   Bokad, the selected day); gold means "look here" or "not yet sealed"
   (today, pending). Mobile first: base = 390px, then 720, 1080. */
:root {
  --ground: #efeae5;        /* stone page ground */
  --panel: #e4deda;         /* closed states, quiet fills */
  --surface: #ffffff;       /* tiles, panels, header */
  --field: #f5f1ed;         /* input wells */
  --ink: #231b1d;
  --muted: #5f5558;         /* 6.0:1 on ground, 7.2:1 on white */
  --rule: #d9d1cb;          /* hairlines and the header edge */
  --rule-strong: #b9aea7;   /* hover rings: ~2:1, visible on ground and white */
  --accent: #6b1e2e;        /* garnet; 11.4:1 with white */
  --accent-hover: #521522;
  --on-accent: #ffffff;
  --select-tint: #f7ecee;
  --gold-light: #d4b15c;    /* today disc, count disc, focus halo; never text */
  --on-gold: #231b1d;
  --pending: #231b1d;
  --pending-bg: #f3e4bc;
  --closed-ink: #4f4649;    /* 6.8:1 on --panel */
  --danger: #9e2a12;        /* rust, never garnet; 6.3:1 on --danger-bg */
  --danger-hover: #7f200d;
  --danger-bg: #fbe6df;
  --scrim: rgb(35 27 29 / 0.5);  /* --ink at 50%, for the confirm dialog's backdrop */
  --shade: rgb(35 27 29 / 0.14); /* --ink at 14%: the scroll shade on the terms dialog's text */
  --surface-clear: rgb(255 255 255 / 0); /* --surface, see-through, for fading into it */
  /* Three self-hosted faces: Jost for what you recognise or press, Inter
     for what you read or type, JetBrains Mono for codes and links. */
  --font-display: "Jost", "Futura PT", Futura, "Avenir Next", sans-serif;
  --font-text: "Inter", "Inter Fallback", sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;
  /* Three clear levels on an 18px body: secondary text (xs/sm) steps well
     below it, headings (lg/2xl) above it without shouting. */
  --fs-xs: 0.8125rem; --fs-sm: 0.875rem; --fs-md: 1rem; --fs-lg: 1.125rem; --fs-2xl: 1.75rem;
  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 24px; --space-6: 32px; --space-7: 48px;
  --tap: 48px;
  --tap-lg: 52px;             /* 48px from 720px, below */
  --hairline: 1.5px;
  --ring: 0 0 0 7px var(--gold-light);           /* focus halo, outside the ink outline */
  --ring-selected: 0 0 0 3px var(--accent);      /* the open day */
  --radius-xs: 4px;
  --radius-sm: 9px;
  --radius: 12px;
  --radius-tile: 14px;
  --radius-card: 18px;
  --radius-panel: 22px;
  --radius-pill: 999px;
}
/* All three faces are self-hosted (SIL OFL: static/fonts/OFL.txt for Jost,
   OFL-Inter.txt, OFL-JetBrainsMono.txt) so no visitor IP reaches a font
   CDN. One variable file per subset covers the weights used. ?v= is the
   font version and makes the files cache as immutable; a preload in
   layout.templ must use the identical URL. */
@font-face { font-family: "Jost"; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url("../fonts/jost-v20-latin.woff2?v=20") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Jost"; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url("../fonts/jost-v20-latin-ext.woff2?v=20") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url("../fonts/inter-4.1-latin.woff2?v=4.1") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url("../fonts/inter-4.1-latin-ext.woff2?v=4.1") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
/* Metric-matched stand-in while Inter loads, so the swap doesn't move text. */
@font-face { font-family: "Inter Fallback"; src: local("Arial"), local("Helvetica"), local("Roboto");
  size-adjust: 107%; ascent-override: 90%; descent-override: 22.4%; line-gap-override: 0%; }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/jetbrains-mono-2.304-latin.woff2?v=2.304") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
/* Phones keep the roomier 52px controls; with a pointer 48px is plenty. */
@media (min-width: 720px) { :root { --tap-lg: 48px; } }
*, *::before, *::after { box-sizing: border-box; }
html { background: var(--ground); color: var(--ink); font: 112.5%/1.5 var(--font-text); font-feature-settings: "cv05"; -webkit-text-size-adjust: 100%; }
/* Jost for what you recognise or press; everything else reads in Inter. */
.wordmark, h1, h2, .page-title, .cal__title, .dp__date, .dp__big, .topbar__link, .subnav__link, .button, .field__label, .status, .chip, .count, .day__num, .cal__weekdays, .row__title { font-family: var(--font-display); }
/* Jost and JetBrains Mono don't have cv05 (the tailed l); html's setting is
   for Inter body text only, so reset it here rather than let it inherit. */
.wordmark, h1, h2, .page-title, .cal__title, .dp__date, .dp__big, .topbar__link, .subnav__link, .button, .field__label, .status, .chip, .count, .day__num, .cal__weekdays, .row__title { font-feature-settings: normal; }
code, .url { font-family: var(--font-mono); font-size: 0.9em; font-feature-settings: normal; }
body { margin: 0; min-height: 100dvh; display: flex; flex-direction: column; }
a { color: var(--accent); text-underline-offset: 3px; }
:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; box-shadow: var(--ring); }
/* Headings and notices take focus only so screen readers announce them. */
[tabindex="-1"]:focus { outline: none; box-shadow: none; }
/* These set their own box-shadow, which would drop the gold halo. */
.button--secondary:focus-visible { box-shadow: inset 0 0 0 2px var(--ink), var(--ring); }
.field__input:focus-visible, textarea:focus-visible, select:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; box-shadow: inset 0 -2px 0 var(--ink), var(--ring); }
.field__input[aria-invalid="true"]:focus-visible, textarea[aria-invalid="true"]:focus-visible, select[aria-invalid="true"]:focus-visible { box-shadow: inset 0 0 0 3px var(--danger), var(--ring); }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; animation: none !important; } }
.skip { position: absolute; left: -10000px; } .skip:focus { left: var(--space-4); top: var(--space-4); background: var(--surface); padding: var(--space-2); z-index: 10; }
/* One page width everywhere, the calendar's, so the header never shifts
   between pages; narrow pages keep their own 40rem column inside it. */
.wrap { width: 100%; max-width: 1280px; margin: 0 auto; padding-inline: var(--space-4); }
@media (min-width: 720px) { .wrap { padding-inline: var(--space-5); } }
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Header */
.topbar { background: var(--surface); border-bottom: 3px solid var(--rule); }
.topbar__inner { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2) var(--space-4); min-height: 64px; flex-wrap: wrap; padding-top: var(--space-2); padding-bottom: var(--space-2); }
.wordmark { display: inline-flex; align-items: center; gap: var(--space-3); color: var(--ink); text-decoration: none; font-weight: 600; font-size: var(--fs-lg); line-height: 1.1; }
.wordmark__rings { flex: none; color: var(--accent); }
.topbar__nav { display: flex; gap: var(--space-1); align-items: center; flex-wrap: wrap; }
.topbar__link { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap); padding: 0 var(--space-4); border: 0; border-radius: var(--radius-pill); background: none; color: inherit; font: 500 var(--fs-md)/1 var(--font-display); text-decoration: none; margin: 0; appearance: none; cursor: pointer; }
.topbar__link:hover { background: var(--ground); }
.topbar__link--current, .topbar__link--current:hover { background: var(--accent); color: var(--on-accent); }
/* A flex form is exactly its button's box, so Logga ut lines up with the
   links beside it by construction, not by the body's line-height. */
.topbar__form { display: flex; }
/* The account group: after a short rounded tick, so signing in or out
   never reads as one more page. The tick is a border, not a background,
   so it survives forced-colors mode. */
.topbar__account { display: flex; align-items: center; gap: var(--space-1); margin-left: var(--space-2); }
.topbar__account::before { content: ""; width: 0; height: 1.25em; margin-right: var(--space-2); border-left: 2px solid var(--rule-strong); border-radius: var(--radius-pill); }
/* The header links (pages, then the account group) fit one narrow row only
   with slimmer pills. */
@media (max-width: 479px) {
  .topbar__nav { gap: 0; } .topbar__link { padding: 0 var(--space-2); }
  .topbar__account { margin-left: var(--space-1); } .topbar__account::before { margin-right: var(--space-1); }
}
.count { display: inline-grid; place-items: center; min-width: 1.6em; height: 1.6em; padding: 0 var(--space-1); border-radius: var(--radius-pill); background: var(--gold-light); color: var(--on-gold); font-size: var(--fs-xs); font-weight: 600; }
main { flex: 1; padding-block: var(--space-5) var(--space-7); }
@media (min-width: 720px) { main { padding-block: var(--space-6) var(--space-7); } }

/* Type */
h1, .page-title { font-weight: 500; font-size: var(--fs-2xl); line-height: 1.15; letter-spacing: -0.01em; margin: 0 0 var(--space-4); }
h2 { font-weight: 500; font-size: var(--fs-lg); line-height: 1.2; margin: var(--space-5) 0 var(--space-3); }
.panel > :first-child { margin-top: 0; }
.panel > :last-child { margin-bottom: 0; }
.muted { color: var(--muted); }
/* Supporting text: intros, leads and help lines. A step below the body,
   grey, and short enough to break into one or two even lines. */
.lead { font-size: var(--fs-sm); line-height: 1.45; color: var(--muted); max-width: 48ch; margin: var(--space-2) 0 0; text-wrap: pretty; }
.lead + .lead { margin-top: var(--space-1); }
/* Pull a lead up under a plain h1 (which keeps its bottom margin); in a
   .status-head the h1 has none, so the lead's own margin is right there. */
h1 + .lead { margin-top: calc(-1 * var(--space-2)); }
.status-head h1 + .lead { margin-top: var(--space-2); }
.lead + .panel { margin-top: var(--space-4); }
.info { max-width: 62ch; }
.info > :first-child { margin-top: 0; }
.layout { display: grid; grid-template-columns: 1fr; gap: var(--space-5); align-items: start; }
.layout__info { order: -1; }
/* "Välj en dag…" only restates what the calendar shows; the panel appears
   once a day is chosen (from 960px it opens in the drawer instead). */
.layout--cal .layout__day:not(:has(.dp__date)) { display: none; }
.info h2 { font-size: var(--fs-md); }
/* The settings preview's headings are h4 (see views.InfoBlocksNested) but
   look like the calendar page's h2. */
.info__h { font-weight: 500; font-size: var(--fs-md); line-height: 1.2; margin: var(--space-5) 0 var(--space-3); }
.info-preview__title + .info__h { margin-top: var(--space-3); }

/* Notices */
.notice { display: flex; gap: var(--space-3); align-items: flex-start; padding: var(--space-4); margin: 0 0 var(--space-4); border-radius: var(--radius-tile); background: var(--surface); }
.notice::before { content: ""; flex: none; width: 1.5em; height: 1.5em; border-radius: 50%; background: var(--accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5 10.5l3.2 3.2L15 7' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/80% no-repeat; }
.notice--error { background: var(--danger-bg); color: var(--danger); box-shadow: inset 0 0 0 2px var(--danger); }
.notice--error::before { content: "!"; display: grid; place-items: center; background: var(--danger); color: var(--danger-bg); font-weight: 600; }

/* Neutral information and warnings: no tick, which means "done". */
.notice--info { background: var(--panel); }
.notice--info::before { display: none; }
.notice--warn { background: var(--pending-bg); color: var(--pending); box-shadow: inset 0 0 0 2px var(--gold-light); }
.notice--warn::before { content: "!"; display: grid; place-items: center; background: var(--gold-light); color: var(--on-gold); font-weight: 600; }

/* Status: word + fill + dot shape, so it never relies on colour alone.
   Filled dot = decided, hollow ring = waiting, slashed ring = closed. */
.status, .chip { display: inline-flex; align-items: center; gap: var(--space-2); border-radius: var(--radius-pill); font-weight: 500; }
.status { padding: var(--space-1) var(--space-3) var(--space-1) var(--space-2); font-size: var(--fs-sm); line-height: 1.3; white-space: nowrap; }
.status::before, .chip::before { content: ""; flex: none; width: 0.62em; height: 0.62em; border-radius: 50%; }
.status--approved, .chip--approved { background: var(--accent); color: var(--on-accent); }
.status--approved::before, .chip--approved::before { background: currentColor; }
.status--pending, .chip--pending { background: var(--pending-bg); color: var(--pending); }
.status--pending::before, .chip--pending::before { box-shadow: inset 0 0 0 2px currentColor; }
.chip--clash { box-shadow: inset 0 0 0 2px var(--danger); }
.status--rejected, .status--cancelled { background: var(--panel); color: var(--closed-ink); }
.status--rejected::before, .status--cancelled::before { box-shadow: inset 0 0 0 2px currentColor; background: linear-gradient(45deg, transparent 43%, currentColor 43% 57%, transparent 57%); }
.status--conflict { background: var(--danger-bg); color: var(--danger); }
.status--conflict::before { content: "!"; width: 1.15em; height: 1.15em; display: grid; place-items: center; background: var(--danger); color: var(--danger-bg); font-weight: 600; font-size: 0.8em; }
/* Info: an overlap that needs attention but blocks nothing. */
.status--info { background: var(--surface); color: var(--ink); box-shadow: inset 0 0 0 var(--hairline) var(--rule-strong); }
.status--info::before { box-shadow: inset 0 0 0 2px currentColor; }
.status + .status { margin-left: var(--space-1); }

/* Buttons and forms */
.button { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); min-height: var(--tap-lg); padding: 0 calc(var(--space-4) + var(--space-1)); background: var(--accent); color: var(--on-accent); border: 0; border-radius: var(--radius-pill); font: 500 var(--fs-md)/1 var(--font-display); text-decoration: none; cursor: pointer; white-space: nowrap; }
.button--secondary { background: var(--surface); color: var(--ink); box-shadow: inset 0 0 0 2px var(--ink); }
.button--danger { background: var(--danger); color: var(--on-accent); }
.button--danger-text { color: var(--danger); box-shadow: inset 0 0 0 2px var(--danger); }
.button--block { width: 100%; }
.button:hover:not(:disabled) { background: var(--accent-hover); }
.button--secondary:hover:not(:disabled) { background: var(--ground); }
.button--danger:hover:not(:disabled) { background: var(--danger-hover); }
.button--danger-text:hover:not(:disabled) { background: var(--danger-bg); }
.button--ghost { background: none; color: var(--ink); }
.button--ghost:hover:not(:disabled) { background: var(--panel); }
.button:active:not(:disabled) { transform: translateY(1px); }
.button:disabled { opacity: 0.5; cursor: not-allowed; }
.field { display: block; margin-bottom: var(--space-4); }
/* Labels rank below what is typed into the field. */
.field__label { display: block; font-weight: 500; font-size: var(--fs-sm); margin-bottom: var(--space-1); }
.field__input, textarea, select { width: 100%; min-height: var(--tap-lg); padding: var(--space-3) var(--space-4); border: 0; border-radius: var(--radius) var(--radius) var(--radius-xs) var(--radius-xs); background: var(--field); box-shadow: inset 0 -2px 0 var(--ink); font: inherit; font-family: var(--font-text); color: inherit; }
/* A select reads as a field: no native chrome, a muted chevron where the
   picker icons of date and time fields sit. */
/* %235f5558 in the chevron below is --muted (#5f5558) URL-encoded; keep
   the two in sync if --muted ever changes. */
select { appearance: none; -webkit-appearance: none; padding-right: calc(var(--space-4) + 1.5em); background: var(--field) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 6l4 4 4-4' fill='none' stroke='%235f5558' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right var(--space-4) center / 1em; cursor: pointer; }
input::-webkit-calendar-picker-indicator { opacity: 0.7; cursor: pointer; }
/* iOS Safari gives native date and time fields an intrinsic minimum width
   that ignores width: 100%, so they spill out of their grid cell and card;
   it also centres their value. Drop the native chrome and let them shrink. */
input[type="date"], input[type="time"] { -webkit-appearance: none; appearance: none; min-width: 0; max-width: 100%; display: block; }
input::-webkit-date-and-time-value { text-align: left; margin: 0; }
textarea { min-height: 120px; }
textarea[rows] { min-height: 0; }
.field__input[aria-invalid="true"], textarea[aria-invalid="true"], select[aria-invalid="true"] { background-color: var(--danger-bg); box-shadow: inset 0 0 0 3px var(--danger); }
.field__error { display: flex; gap: var(--space-2); align-items: center; color: var(--danger); font-weight: 600; font-size: var(--fs-sm); margin-top: var(--space-2); }
.field__error::before { content: "!"; flex: none; width: 1.4em; height: 1.4em; border-radius: 50%; background: var(--danger); color: var(--danger-bg); display: grid; place-items: center; font-size: 0.85em; }
.field__hint { display: block; color: var(--muted); font-size: var(--fs-sm); margin-top: var(--space-1); }
/* A label's "(valfritt)" aside, split off by fieldLabel. */
.field__note { color: var(--muted); font-weight: 400; }
.field--short .field__input { max-width: 8rem; }
.field + .field__hint { margin-top: calc(var(--space-1) - var(--space-4)); }
.field__hint--warn { color: var(--danger); font-weight: 600; }
textarea[name="public_info"] { min-height: 16rem; }
.info-preview__count { margin-top: var(--space-1); }
.info-preview { margin-top: var(--space-3); padding: var(--space-4); border-radius: var(--radius); box-shadow: inset 0 0 0 var(--hairline) var(--rule); }
.info-preview__title { margin: 0 0 var(--space-2); font-size: var(--fs-sm); color: var(--muted); }
input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.field__input:hover:not(:focus-visible):not(:disabled):not([aria-invalid="true"]), textarea:hover:not(:focus-visible):not(:disabled):not([aria-invalid="true"]), select:hover:not(:focus-visible):not(:disabled):not([aria-invalid="true"]) { box-shadow: inset 0 -3px 0 var(--ink); }
.field__input:disabled, textarea:disabled, select:disabled { opacity: 0.5; cursor: not-allowed; }
.form { max-width: 600px; }
.form__row { display: grid; gap: var(--space-3); grid-template-columns: 1fr 1fr; }
/* Below 480px two columns don't leave room for select option text (e.g.
   Upprepa's "Varannan vecka" next to a date); stack instead. This also
   stacks the Från/Till time row, which is fine at this width. */
@media (max-width: 479px) { .form__row { grid-template-columns: 1fr; } }
.form__actions { display: flex; gap: var(--space-3); flex-wrap: wrap; margin-top: var(--space-5); }
.panel .form__actions:first-child, .form__actions--tight { margin-top: 0; }
.check { display: flex; gap: var(--space-3); align-items: flex-start; min-height: var(--tap); margin-bottom: var(--space-4); cursor: pointer; }
.check input { flex: none; appearance: none; -webkit-appearance: none; width: 24px; height: 24px; margin: 2px 0 0; border-radius: var(--radius-xs); background: var(--field); box-shadow: inset 0 0 0 2px var(--ink); cursor: pointer; }
.check input:checked { background: var(--accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5 10.5l3.2 3.2L15 7' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/80% no-repeat; box-shadow: none; }
.check input:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; box-shadow: inset 0 0 0 2px var(--ink), var(--ring); }
.check input:checked:focus-visible { box-shadow: var(--ring); }
/* A radio in a .check row is round, and marked with a dot, not a tick. */
.check input[type=radio] { border-radius: 50%; }
.check input[type=radio]:checked { background: var(--field); box-shadow: inset 0 0 0 2px var(--accent), inset 0 0 0 6px var(--field), inset 0 0 0 12px var(--accent); }
.check input[type=radio]:checked:focus-visible { box-shadow: inset 0 0 0 2px var(--accent), inset 0 0 0 6px var(--field), inset 0 0 0 12px var(--accent), var(--ring); }
/* Windows high-contrast mode forces the box-shadow away and the background
   to Canvas, which erases the custom box; fall back to the native
   checkbox so it stays visible and operable. */
@media (forced-colors: active) { .check input { appearance: auto; -webkit-appearance: auto; } }
.check .field__hint { display: block; margin-top: 0; }
/* A choice that belongs to the radio above it, indented under its label. */
.check--nested { margin-left: calc(24px + var(--space-3)); }
.field__hint--group { margin: calc(var(--space-1) - var(--space-4)) 0 var(--space-4); }
/* The end date only matters for multi-day bookings, but stays visible if it
   holds an error, or the error would be invisible. */
.form:has(#flerdag:not(:checked)) .enddate:not(:has([aria-invalid="true"])) { display: none; }
/* "Till och med" only matters once a repeat is chosen, but stays visible if
   it holds an error, or the error would be invisible. */
.form:has(select[name="repeat"] option[value=""]:checked) .until:not(:has([aria-invalid="true"])) { display: none; }
.dayinfo__words { font-weight: 600; margin-top: 0; }
/* The chosen time in words: a ruled aside, not a filled box, so it can't
   be mistaken for another (disabled) input. */
.dayinfo { margin: 0 0 var(--space-4); padding: var(--space-1) 0 var(--space-1) var(--space-4); border-left: 3px solid var(--rule-strong); }
.timefields__row { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr); gap: 0 var(--space-3); align-items: start; }
/* The series page changes only the times: two columns, on every width. */
.timefields__row--times, .timefields__row.timefields__row--times { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.timefields__row.timefields__row--times > :first-child { grid-column: auto; }
/* A series' dates: one line each, grouped by month under a small label.
   Only what differs from the series (a changed title, a status other than
   Godkänd, a clash) gets ink. */
.dates { list-style: none; padding: 0; margin: 0; }
.dates > li + li { border-top: var(--hairline) solid var(--rule); }
.date { display: grid; grid-template-columns: 6.5rem 7.5rem auto minmax(0, 1fr); grid-template-areas: "day time badges note"; align-items: center; gap: var(--space-1) var(--space-3); min-height: var(--tap); padding: var(--space-2); margin: 0 calc(-1 * var(--space-2)); border-radius: var(--radius-sm); color: var(--ink); text-decoration: none; font-variant-numeric: tabular-nums; }
.date:hover { background: var(--field); }
.date__day { grid-area: day; font-weight: 600; }
.date__time { grid-area: time; color: var(--muted); }
.date__note { grid-area: note; color: var(--muted); font-size: var(--fs-sm); overflow-wrap: anywhere; }
/* Right after the time, so a badge reads with its date on a wide screen. */
.date__badges { grid-area: badges; display: flex; flex-wrap: wrap; gap: var(--space-2); }
.date__badges:empty { display: none; }
.date--closed .date__day { font-weight: 500; color: var(--muted); }
.dates__month { margin: var(--space-4) 0 var(--space-1); color: var(--muted); font: 500 var(--fs-sm)/1.3 var(--font-display); }
.status-card__group > .dates__month:first-of-type { margin-top: var(--space-2); }
@media (max-width: 479px) {
  /* Too narrow for a badge beside the time: badges and a changed title
     get their own lines under the date. */
  .date { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "day time" "badges badges" "note note"; }
  .date__note:empty { display: none; }
}
@media (max-width: 479px) {
  .timefields__row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .timefields__row > :first-child { grid-column: 1 / -1; }
}
.dayinfo > :last-child { margin-bottom: 0; }
.privacy { color: var(--muted); font-size: var(--fs-sm); line-height: 1.45; max-width: 48ch; margin: var(--space-5) 0 0; text-wrap: pretty; }
.privacy + .form__actions { margin-top: var(--space-4); }
.hp { position: absolute; left: -10000px; }

/* Admin shell (AdminLayout): a garnet Administration band under the
   header, then underline tabs, so the admin level never reads as a second
   row of header pills. The .admin scope is a little denser than the public
   site: tighter controls on a desktop, smaller corners. It sits on the tabs'
   wrapper and on <main>, never on <body>, which hx-boost doesn't swap. */
.adminband { background: var(--accent); color: var(--on-accent); }
.adminband__inner { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0 var(--space-4); min-height: 32px; padding-block: var(--space-1); font-size: var(--fs-sm); }
.adminband__title { font: 500 var(--fs-xs)/1.2 var(--font-display); letter-spacing: .08em; text-transform: uppercase; }
.adminband__who { opacity: .9; overflow-wrap: anywhere; }
.admin { --radius-panel: 14px; --radius-card: 12px; --radius-tile: 10px; }
@media (min-width: 720px) { .admin { --tap: 44px; --tap-lg: 44px; } }
.admin__nav { padding-top: var(--space-3); }
main.admin { padding-top: var(--space-4); }
main.admin > .notice { padding-block: var(--space-3); }

/* The phone menu (views.menu): below 720px the header links fold into a
   Meny button that opens a native popover as a bottom sheet. Only where
   popovers work; elsewhere the links stay in the header. */
.menubtn, .sheet { display: none; }
@supports selector(:popover-open) {
  @media (max-width: 719px) {
    .topbar__nav { display: none; }
    /* One row: a long lodge name wraps beside the button, not above it. */
    .topbar__inner { flex-wrap: nowrap; }
    .wordmark { min-width: 0; }
    .menubtn { flex: none; display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap); padding: 0 var(--space-4); border: 0; border-radius: var(--radius-pill); background: var(--ink); color: var(--surface); font: 500 var(--fs-md)/1 var(--font-display); cursor: pointer; }
    .sheet:popover-open { display: block; position: fixed; inset: auto 0 0 0; width: 100%; max-width: none; max-height: 85dvh; margin: 0; overflow-y: auto; border: 0; border-radius: var(--radius-panel) var(--radius-panel) 0 0; padding: var(--space-3) var(--space-4) calc(var(--space-5) + env(safe-area-inset-bottom)); background: var(--surface); color: var(--ink); }
    .sheet::backdrop { background: var(--scrim); }
  }
}
.sheet__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-1); }
.sheet__title { margin: 0; color: var(--muted); font: 500 var(--fs-xs)/1.2 var(--font-display); letter-spacing: .08em; text-transform: uppercase; }
.sheet__close { display: grid; place-items: center; width: var(--tap); height: var(--tap); margin-right: calc(-1 * var(--space-2)); border: 0; border-radius: 50%; background: none; color: var(--ink); cursor: pointer; }
.sheet__close:hover { background: var(--ground); }
.sheet__list { display: flex; flex-direction: column; }
.sheet__form { margin: 0; }
/* The rule is inset to the link text, like the top bar's tick is kept
   short; the links themselves stay aligned with the pages above. */
.sheet__group { position: relative; margin-top: var(--space-3); padding-top: var(--space-3); }
.sheet__group::before { content: ""; position: absolute; top: 0; inset-inline: var(--space-3); border-top: var(--hairline) solid var(--rule); }
.sheet__who { margin: 0 0 var(--space-1); padding: 0 var(--space-3); color: var(--muted); font: 500 var(--fs-xs)/1.2 var(--font-display); letter-spacing: .08em; text-transform: uppercase; overflow-wrap: anywhere; }
.sheet__link { display: flex; align-items: center; gap: var(--space-2); width: 100%; min-height: var(--tap); padding: 0 var(--space-3); border: 0; border-radius: var(--radius-sm); background: none; color: var(--ink); font: 500 var(--fs-lg)/1 var(--font-display); text-align: left; text-decoration: none; cursor: pointer; }
.sheet__link:hover { background: var(--ground); }
.sheet__link--current, .sheet__link--current:hover { background: var(--select-tint); box-shadow: inset 3px 0 0 var(--accent); }
@media (prefers-reduced-motion: no-preference) {
  .sheet:popover-open { animation: sheet-in .2s ease-out; }
  .sheet:popover-open::backdrop { animation: fade-in .2s ease-out; }
}
@keyframes sheet-in { from { transform: translateY(100%); } }

/* Underline tabs: the admin pages, and the login page's two forms */
.subnav { display: flex; gap: var(--space-5); border-bottom: var(--hairline) solid var(--rule-strong); }
.subnav__link { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap); padding: 0 2px; margin-bottom: calc(-1 * var(--hairline)); border-bottom: 3px solid transparent; color: var(--muted); font: 500 var(--fs-md)/1 var(--font-display); text-decoration: none; white-space: nowrap; }
.subnav__link:hover { color: var(--ink); border-bottom-color: var(--rule-strong); }
.subnav__link--current, .subnav__link--current:hover { color: var(--ink); border-bottom-color: var(--accent); }
/* Konto is the admin's own, not the lodge's: it sits apart, at the end. */
.subnav__link--end { margin-left: auto; }
@media (max-width: 719px) {
  .subnav { gap: var(--space-4); flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin-inline: calc(-1 * var(--space-4)); padding-inline: var(--space-4); }
  .subnav::-webkit-scrollbar { display: none; }
  /* More tabs off to the right: fade the trailing edge until the strip is
     scrolled to its end (app.js sets .subnav--end). */
  .subnav:not(.subnav--end) { -webkit-mask-image: linear-gradient(to right, var(--ink) calc(100% - 3rem), transparent); mask-image: linear-gradient(to right, var(--ink) calc(100% - 3rem), transparent); }
}
/* Admin lists: one white sheet of hairline-divided rows, the date first
   so a list reads down its dates. */
.rows { list-style: none; padding: 0; margin: 0; background: var(--surface); border-radius: var(--radius-card); overflow: hidden; }
/* A list reads best in a measure, not across the whole 1280px page: capped,
   the badges stay beside the row they belong to. */
.rows, .filters__summary, .panel.empty { max-width: 56rem; }
.rows > li + li { border-top: var(--hairline) solid var(--rule); }
.row { display: grid; gap: 2px var(--space-4); padding: var(--space-3) var(--space-4); color: var(--ink); text-decoration: none; }
.row:hover { background: var(--field); box-shadow: inset 3px 0 0 var(--rule-strong); }
.row--closed { color: var(--muted); }
.row__title { font-weight: 600; font-size: var(--fs-md); }
.row--closed .row__title { font-weight: 500; }
.row__when { font-size: var(--fs-sm); font-variant-numeric: tabular-nums; }
.row__date { font-weight: 600; }
.row__time { color: var(--muted); }
.row__sub { color: var(--muted); font-size: var(--fs-sm); }
.row__meta::before { content: " · "; }
.row__status { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-1); }
.row__status:empty { display: none; }
.row__status .status + .status { margin-left: 0; }
/* In a list, Godkänd is the common case: tinted, so pending and clashes
   stand out instead of drowning in a column of solid garnet. */
.row .status--approved { background: var(--select-tint); color: var(--accent); }
/* From 720px the date is a column, day over time; from 960px the status
   badges get the next column, so they read down the list like the dates. */
@media (min-width: 720px) {
  .row { grid-template-columns: 10rem minmax(0, 1fr); grid-template-areas: "when title" "when sub" "when status"; align-items: start; }
  .row__when { grid-area: when; padding-top: 2px; }
  .row__date, .row__time { display: block; }
  .row__title { grid-area: title; } .row__sub { grid-area: sub; } .row__status { grid-area: status; }
}
@media (min-width: 960px) {
  .row { grid-template-columns: 10rem 12.5rem minmax(0, 1fr); grid-template-areas: "when status title" "when status sub"; }
  .row__status { flex-direction: column; align-items: flex-start; gap: var(--space-1); margin-top: 0; padding-top: 2px; }
}
/* "Passerade utan svar": the reject button sits beside its row. */
.rows__item--action { display: flex; flex-wrap: wrap; align-items: center; }
.rows__item--action .row { flex: 1 1 24rem; }
.rows__action { padding: 0 var(--space-4) var(--space-3); }
@media (min-width: 720px) { .rows__action { padding: var(--space-3) var(--space-4); } }
.button--compact { min-height: var(--tap); padding: 0 var(--space-4); font-size: var(--fs-sm); }
.empty > p { margin: 0; }
.empty > p + p { margin-top: var(--space-2); }

/* Lists */
.list { list-style: none; padding: 0; margin: 0; }
.list__item { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-3); align-items: center; padding: var(--space-3) 0; border-top: var(--hairline) solid var(--rule); }
.dl { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-3) var(--space-5); margin: 0; }
.dl dt { color: var(--muted); } .dl dd { margin: 0; font-variant-numeric: tabular-nums; }
input[type="time"], input[type="date"] { font-variant-numeric: tabular-nums; }
.url { word-break: break-all; padding: 2px var(--space-2); border-radius: var(--radius-xs); background: var(--field); }
@media (max-width: 719px) {
  .dl { grid-template-columns: 1fr; gap: 2px; }
  .dl dt { margin-top: var(--space-2); font-size: var(--fs-sm); }
}
/* Two by two (status and type, then the dates) with the buttons on their
   own row, from a small phone up to a tablet; one compact bar from 960px. */
.filters { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); align-items: end; margin-bottom: var(--space-3); }
.filters__actions { grid-column: 1 / -1; display: flex; gap: var(--space-2); align-items: center; }
.filters__search { grid-column: 1 / -1; max-width: 32rem; }
/* A filter bar, not a form: lighter controls than the 52px form fields. */
.filters select, .filters .field__input { min-height: var(--tap); padding-block: var(--space-2); padding-left: var(--space-3); font-size: var(--fs-sm); }
/* Two dates side by side on a 375px phone: keep the picker icon close. */
.filters .field__input { padding-right: var(--space-2); }
.filters .field { margin-bottom: 0; }
.filters .button { min-height: var(--tap); }
@media (min-width: 960px) {
  .filters { grid-template-columns: repeat(4, minmax(0, 12rem)) auto; justify-content: start; }
  .filters__actions { grid-column: auto; }
  .filters select, .filters .field__input, .filters .button { min-height: 40px; }
}
.filters__summary { margin: 0 0 var(--space-4); color: var(--muted); }
.rows__month { margin: var(--space-5) 0 var(--space-3); font-size: var(--fs-lg); }
.detail-meta { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-3); align-items: center; margin: 0 0 var(--space-4); }
.status-head .detail-meta { margin: var(--space-3) 0 0; }
/* The booking page: deciding leads. On a phone the actions come first;
   from 960px they sit beside the facts and stay in view. */
.detail-actions { order: -1; }
@media (min-width: 960px) { .detail-actions { order: 0; position: sticky; top: var(--space-4); } }
/* On a series page the dates come first on a phone; the forms change them. */
.series-actions { order: 0; }
/* Disclosures (<details class="disclosure">): a garnet summary led by a
   chevron that turns when open, and the content set in from a rule under
   the chevron, so it reads as belonging to the line that opened it. The
   danger zones' summary is rust. */
.disclosure > summary { display: flex; align-items: center; gap: var(--space-2); min-height: var(--tap); color: var(--accent); font: 500 var(--fs-md)/1.25 var(--font-display); font-feature-settings: normal; list-style: none; cursor: pointer; }
.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure > summary::before { content: ""; flex: none; width: 16px; height: 16px; background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M6 3.5 10.5 8 6 12.5' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M6 3.5 10.5 8 6 12.5' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; transition: transform .15s ease-out; }
.disclosure[open] > summary::before { transform: rotate(90deg); }
.disclosure[open] > summary { margin-bottom: var(--space-2); }
.disclosure__body { margin-left: 6px; padding: var(--space-1) 0 var(--space-1) var(--space-4); border-left: 3px solid var(--rule); }
.disclosure__body > :first-child { margin-top: 0; }
.disclosure__body > :last-child { margin-bottom: 0; }
.danger-zone > summary { color: var(--danger); }
.dl + .disclosure { margin-top: var(--space-3); }

/* Calendar */
.cal__head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-3); }
.cal__title { margin: 0; }
.cal__nav { display: flex; gap: var(--space-2); }
.cal__nav .button { min-width: var(--tap-lg); padding: 0 var(--space-4); }
.cal__navtext { display: none; }
.cal__weekdays, .cal__week { display: none; }
.cal__key { margin: 0 0 var(--space-4); }
.cal__legend { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0 0 var(--space-2); }
.cal__legend-help { margin: 0; }
/* The legend's pills are labels, not buttons: a size below the grid chips. */
.cal__legend .status { font-size: var(--fs-xs); padding: 2px var(--space-2) 2px 6px; gap: 6px; }
.cal__legend .status::before { width: 0.55em; height: 0.55em; }
.cal__list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.cal__list .day { display: flex; gap: var(--space-3); align-items: center; min-height: 60px; padding: var(--space-2) var(--space-3); border-radius: var(--radius-tile); background: var(--surface); }
.cal__list .day--past { background: var(--field); }
.day__free { color: var(--muted); font-size: var(--fs-sm); }
.day--past .day__num { color: var(--muted); }
.cal__list .day > div { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; flex: 1; }
.cal__weeksep { padding: var(--space-2) var(--space-1) 0; color: var(--muted); font-size: var(--fs-xs); font-weight: 600; }
.cal__weeksep:first-child { padding-top: 0; }
.cal__past { list-style: none; }
.cal__past .cal__list { margin-top: var(--space-2); }
.day { position: relative; }
.day__num::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
a.chip { position: relative; z-index: 1; }
.day:hover { box-shadow: 0 0 0 2px var(--rule-strong); }
.day--selected:hover { box-shadow: var(--ring-selected); }
.day__num { display: inline-flex; align-items: center; gap: var(--space-2); min-height: 2em; color: inherit; font-weight: 500; font-size: var(--fs-lg); line-height: 1; text-decoration: none; }
.cal__list .day__num { min-width: 4.6em; flex: none; }
.day__wd { min-width: 1.9em; }
/* Today: a gold disc around the number only, and a gold edge on the tile
   (inside, so it never meets the garnet ring of the selected day). */
.day__n { display: inline-grid; place-items: center; width: 1.85em; height: 1.85em; border-radius: 50%; font-variant-numeric: tabular-nums; }
.day--today .day__n { background: var(--gold-light); color: var(--on-gold); font-weight: 600; }
.day__today { font-size: var(--fs-xs); font-weight: 600; color: var(--muted); white-space: nowrap; }
.day--today, .cal__list .day--today { box-shadow: inset 0 0 0 2px var(--gold-light); }
.day--today:hover { box-shadow: 0 0 0 2px var(--rule-strong), inset 0 0 0 2px var(--gold-light); }
.day--selected { box-shadow: var(--ring-selected); background: var(--select-tint); }
.cal__list .day--selected { background: var(--select-tint); box-shadow: var(--ring-selected); }
.day--today.day--selected, .cal__list .day--today.day--selected, .day--today.day--selected:hover { box-shadow: var(--ring-selected), inset 0 0 0 2px var(--gold-light); }
.chip { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--space-2); font-size: var(--fs-sm); line-height: 1.25; padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm); text-decoration: none; font-variant-numeric: tabular-nums; }
.chip::before { align-self: center; }
.chip__title { font-weight: 600; overflow-wrap: anywhere; }
/* Grid chips: a small inline dot keeps the shape cue; the time sits on
   line one and is never cut (in the narrowest cells it wraps after the
   dash), the title on one line of its own, cut with an ellipsis rather
   than hyphenated. The full time ("18:30–22:00") needs 1200px; below that
   the short one ("18:30–22"), and below 960px no title. The day panel
   and the title attribute carry the rest. */
.cal__week .chip { display: block; position: relative; overflow: hidden; font-size: var(--fs-xs); padding: var(--space-1) var(--space-2) var(--space-1) calc(var(--space-2) + 0.5em + var(--space-1)); border-radius: var(--radius-sm); }
/* Pinned to the first line, so a wrapped time never leaves it behind. */
.cal__week .chip::before { position: absolute; left: var(--space-2); top: calc(var(--space-1) + 0.4em); width: 0.5em; height: 0.5em; }
.cal__week .chip__t { font-weight: 600; }
.cal__week .chip__t--long { display: none; }
.cal__week .chip__title { display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; overflow-wrap: normal; font-weight: 500; }
@media (max-width: 959px) { .cal__week .chip__title { display: none; } }
@media (min-width: 720px) {
  .cal__list { display: none; }
  .cal__weekdays, .cal__week { display: grid; grid-template-columns: 1.5rem repeat(7, minmax(0, 1fr)); gap: var(--space-1); }
  .cal__wk, .cal__wkhead { padding: var(--space-2) 0 0; color: var(--muted); font-size: var(--fs-xs); text-align: center; font-variant-numeric: tabular-nums; }
  .cal__weekdays .cal__wkhead { padding: 0; }
  .cal__weekdays { font-size: var(--fs-sm); font-weight: 500; color: var(--muted); margin-bottom: var(--space-2); }
  .cal__weekdays span { padding: 0 var(--space-2); }
  .cal__week { margin-bottom: var(--space-2); }
  .cal__week .day { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; min-height: 96px; padding: var(--space-1); border-radius: var(--radius-tile); background: var(--surface); }
  /* Three tiers: days to come are white tiles, days gone by a quiet well,
     the neighbouring months' days bare and faded. */
  .cal__week .day--past { background: var(--field); }
  .cal__week .day--out { background: transparent; box-shadow: inset 0 0 0 var(--hairline) var(--rule); }
  .cal__week .day--out .day__n { opacity: 0.55; }
  .cal__week .day--selected { box-shadow: var(--ring-selected); background: var(--select-tint); }
  .cal__week .day--today.day--selected { box-shadow: var(--ring-selected), inset 0 0 0 2px var(--gold-light); }
  .cal__week .day__num { align-self: flex-start; font-size: var(--fs-md); }
  .cal__navtext { display: inline; padding: 0 var(--space-1); }
}
@media (min-width: 960px) {
  .layout { grid-template-columns: 2fr 1fr; grid-template-rows: auto 1fr; grid-template-areas: "cal day" "cal info"; }
  .layout__cal { grid-area: cal; } .layout__day { grid-area: day; } .layout__info { grid-area: info; order: 0; }
  /* The calendar takes the whole (wider) page; the day opens in the drawer
     below. Without JS a chosen day stays in the page, under the month. */
  .layout--cal { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; grid-template-areas: "cal" "day" "info"; }
  .cal__key { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); }
  .cal__key .cal__legend { margin: 0; }
  .cal__legend-help { max-width: none; }
  .cal__week .day { min-height: 112px; padding: var(--space-2); }
  .layout--detail { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); grid-template-rows: none; grid-template-areas: none; }
  .layout--single { grid-template-columns: minmax(0, 42rem); }
}
@media (min-width: 1200px) {
  .cal__week .chip__t--short { display: none; }
  .cal__week .chip__t--long { display: inline; }
}
@media (prefers-reduced-motion: no-preference) { .day, .button, .row { transition: box-shadow .15s, background-color .15s, transform .15s; } }

/* The requester's status page and the request form before it: one 40rem
   column, the flash capped to match. Inside the card, groups sit a steady
   --space-5 apart with a hairline between them; the withdraw/cancel form
   comes last and outlined, never the loudest thing on a thank-you page. */
.status-page, .request-page { max-width: 40rem; }
main:has(.status-page, .request-page) > .notice { max-width: 40rem; }
.status-head { margin-bottom: var(--space-5); }
.status-head h1 { margin: 0; overflow-wrap: anywhere; }
.status-head__kind { margin: 0 0 var(--space-1); color: var(--muted); font: 500 var(--fs-md)/1.3 var(--font-display); }
.status-head__when { margin: var(--space-2) 0 0; font-weight: 500; font-variant-numeric: tabular-nums; }
.status-card { display: flex; flex-direction: column; gap: var(--space-5); }
.status-card__group > * { margin: 0; }
.status-card__group > * + * { margin-top: var(--space-3); }
.status-card__group + .status-card__group { padding-top: var(--space-5); border-top: var(--hairline) solid var(--rule); }
.status-card h2 { font-size: var(--fs-md); }
/* "Skickad" is bookkeeping: smaller as well as grey. */
.status-card .dl dd.muted { font-size: var(--fs-sm); }
.status-link__row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); }
.status-link .url { padding: var(--space-2) var(--space-3); }
.status-cancel { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2) var(--space-4); }
.status-cancel > * + * { margin-top: 0; }
.status-back { margin: var(--space-5) 0 0; }
/* The request form: the card's groups are fieldsets with a legend each. */
.request-page .form { max-width: none; }
.request-page > .lead { margin-bottom: var(--space-5); }
/* Settings. The overview is one row per settings page: its name, what is
   saved there now (cut to one line), and Ändra. A summary in --warn says
   something the lodge needs is missing. */
.settings-rows { margin-top: var(--space-5); }
.settings-row { display: flex; align-items: center; gap: var(--space-4); min-height: var(--tap-lg); padding: var(--space-3) var(--space-4); color: var(--ink); text-decoration: none; }
.settings-row:hover { background: var(--field); box-shadow: inset 3px 0 0 var(--rule-strong); }
.settings-row__text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.settings-row__title { margin: 0; font-size: var(--fs-md); font-weight: 600; }
.settings-row__sub { overflow: hidden; color: var(--muted); font-size: var(--fs-sm); text-overflow: ellipsis; white-space: nowrap; }
.settings-row__sub--warn { color: var(--danger); font-weight: 500; }
.settings-row__go { flex: none; color: var(--accent); font-weight: 500; }
.settings-row__go::after { content: " ›"; }
/* A settings page: the way back to the overview above its heading. */
.settings-back { margin: 0 0 var(--space-3); }
.settings-back a { display: inline-flex; align-items: center; min-height: var(--tap); font-weight: 500; }
/* Spara stays in reach under a long text: the actions stick to the bottom
   of the screen while the form runs past it, as a bar across the card. */
.settings-form .settings-form__actions { position: sticky; bottom: 0; z-index: 1; margin: 0 calc(-1 * var(--space-5)) calc(-1 * var(--space-5)); padding: var(--space-3) var(--space-5); border-top: var(--hairline) solid var(--rule); border-radius: 0 0 var(--radius-panel) var(--radius-panel); background: var(--surface); }
@media (max-width: 719px) { .settings-form .settings-form__actions { margin: 0 calc(-1 * var(--space-4)) calc(-1 * var(--space-4)); padding-inline: var(--space-4); } }
.settings-alerts { margin-top: var(--space-5); }
/* The alert card has no fieldsets, so its headings take the legends' look:
   the card's title like a legend, its list a step below. */
.settings-alerts h2 { font: 500 var(--fs-lg)/1.2 var(--font-display); }
.settings-alerts h3 { font: 500 var(--fs-md)/1.3 var(--font-display); }
/* A booking's history: one line per event, the time after it in grey. */
.history { list-style: none; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.history li { overflow-wrap: anywhere; }
.history .muted { font-size: var(--fs-sm); white-space: nowrap; }
/* Admins: one row each, who on the left and actions on the right,
   wrapping under the address on a phone. The doubled class outranks the
   day panel's stacked .panel .list__item, which comes later. Remove is a quiet text button;
   the confirm dialog is its guard. */
.panel .list__item.admins__item { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2) var(--space-4); }
.admins__who { flex: 1 1 16rem; display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; overflow-wrap: anywhere; }
.admins__name { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); }
.admins__who .muted { font-size: var(--fs-sm); }
.admins .status { font-size: var(--fs-xs); padding: 2px var(--space-2) 2px 6px; gap: 6px; }
.admins .status::before { width: 0.55em; height: 0.55em; }
.admins .status + .status { margin-left: 0; }
.admins .status--conflict::before { width: 1.1em; height: 1.1em; }
.admins__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin-left: auto; }
.button--ghost.button--danger-text { color: var(--danger); box-shadow: none; }
/* The login page: the admin area's underline tabs, one form under each.
   Kept inside the page's column, not bled to the edge like the admin
   strip. Administratör sits apart at the end, like Konto. */
.login__tabs { margin-bottom: var(--space-4); }
@media (max-width: 719px) { .login__tabs { margin-inline: 0; padding-inline: 0; } }
.login .form > .lead { margin: 0 0 var(--space-4); }
.request-page fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.request-page .status-card__group + .status-card__group { border-top: var(--hairline) solid var(--rule); }
/* Floated, so the legend leaves the fieldset's top border (the divider)
   whole instead of sitting in a notch cut out of it. */
.request-page legend { float: left; width: 100%; padding: 0; margin-bottom: var(--space-4); font: 500 var(--fs-lg)/1.2 var(--font-display); }
.request-page legend + * { clear: both; margin-top: 0; }
.request-page .dayinfo { margin-bottom: 0; }
.request-page .timefields .check { margin-bottom: 0; }
.request-page #request-day:empty { display: none; }
.request-page .status-card__group > * + * { margin-top: var(--space-4); }
.request-page .field:last-child, .request-page .timefields > :last-child { margin-bottom: 0; }
@media (min-width: 600px) {
  .request-contact { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0 var(--space-3); align-items: start; }
}
.request-contact .field { margin-bottom: 0; }
.request-contact .field + .field { margin-top: var(--space-4); }
@media (min-width: 600px) { .request-contact .field + .field { margin-top: 0; } }
.request-page .form__actions { margin-top: var(--space-4); }
@media (max-width: 479px) { .request-actions .button { flex: 1 1 100%; } }

/* The rental terms. On the request form a link opens them in a modal
   (app.js): a bottom sheet on a phone, like the Meny, and a centred panel
   from 720px. The head and foot stay put; only the text scrolls, with a
   shade at an edge while there is more to scroll that way. */
.terms-open { margin: 0; }
.link-action { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap); font: 500 var(--fs-md)/1.2 var(--font-display); font-feature-settings: normal; }
.link-action svg { flex: none; }
.terms-dialog { flex-direction: column; padding: 0; border: 0; background: var(--surface); color: var(--ink); overflow: hidden; }
.terms-dialog[open] { display: flex; }
.terms-dialog::backdrop { background: var(--scrim); }
.terms-dialog__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-2) var(--space-3) var(--space-2) var(--space-5); border-bottom: var(--hairline) solid var(--rule); }
.terms-dialog__head h2 { margin: 0; font: 500 var(--fs-lg)/1.2 var(--font-display); }
.terms-dialog__head .sheet__close { margin-right: 0; }
.terms-dialog__body { flex: 1 1 auto; min-height: 0; max-width: none; overflow-y: auto; overscroll-behavior: contain; padding: var(--space-5);
  background:
    linear-gradient(var(--surface) 30%, var(--surface-clear)) top / 100% 24px no-repeat local,
    linear-gradient(var(--surface-clear), var(--surface) 70%) bottom / 100% 24px no-repeat local,
    radial-gradient(farthest-side at 50% 0, var(--shade), transparent) top / 100% 8px no-repeat scroll,
    radial-gradient(farthest-side at 50% 100%, var(--shade), transparent) bottom / 100% 8px no-repeat scroll,
    var(--surface); }
.terms-dialog__body > * { max-width: 62ch; }
.terms-dialog__body:focus-visible { outline-offset: -3px; box-shadow: none; }
.terms-dialog__foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--space-2); padding: var(--space-3) var(--space-5) calc(var(--space-4) + env(safe-area-inset-bottom)); border-top: var(--hairline) solid var(--rule); }
.terms-dialog__page { margin-right: auto; font-size: var(--fs-sm); font-weight: 500; }
@media (min-width: 720px) {
  .terms-dialog { width: min(40rem, calc(100vw - 2 * var(--space-4))); max-height: 85dvh; border-radius: var(--radius-panel); }
}
@media (max-width: 719px) {
  .terms-dialog { position: fixed; inset: auto 0 0 0; width: 100%; max-width: none; max-height: 90dvh; margin: 0; border-radius: var(--radius-panel) var(--radius-panel) 0 0; }
  .terms-dialog__body { padding: var(--space-4); }
  .terms-dialog__foot { flex-direction: column-reverse; align-items: stretch; padding-inline: var(--space-4); }
  .terms-dialog__page { margin: 0; align-self: center; display: inline-flex; align-items: center; min-height: var(--tap); }
}
@media (prefers-reduced-motion: no-preference) {
  .terms-dialog[open]::backdrop { animation: fade-in .2s ease-out; }
}
@media (prefers-reduced-motion: no-preference) and (max-width: 719px) { .terms-dialog[open] { animation: sheet-in .2s ease-out; } }
@media (prefers-reduced-motion: no-preference) and (min-width: 720px) { .terms-dialog[open] { animation: terms-in .2s ease-out; } }
@keyframes terms-in { from { opacity: 0; transform: translateY(8px) scale(.98); } }
/* /villkor: the same text on its own page, and as little else as can be
   when printed. */
.terms-page .panel { max-width: 44rem; }
.terms-page__print { margin: var(--space-5) 0 0; }
@media print {
  .skip, .topbar, .adminband, .admin__nav, .settings-back, .terms-page__print { display: none !important; }
  html, body { background: var(--surface); }
  .terms-page .panel { padding: 0; }
}

/* The Swedish confirm dialog, opened by app.js instead of window.confirm. */
.confirm { max-width: min(28rem, calc(100vw - 2 * var(--space-4))); border: 0; border-radius: var(--radius-panel); padding: var(--space-5); background: var(--surface); color: var(--ink); }
.confirm::backdrop { background: var(--scrim); }
.confirm__text { margin-top: 0; font-weight: 500; }

/* Panels and the day panel */
.panel { background: var(--surface); border-radius: var(--radius-panel); padding: var(--space-5); }
/* Below 720px the panel padding plus the select's chevron padding left too
   little room for option text in a two-column .form__row; tighten it. */
@media (max-width: 719px) { .panel { padding: var(--space-4); } }
.panel .list__item { flex-direction: column; align-items: flex-start; gap: var(--space-1); }
.panel--stack { display: flex; flex-direction: column; gap: var(--space-3); }
.panel--stack > p, .panel--stack .field { margin: 0; }
.panel--stack form { display: flex; flex-direction: column; gap: var(--space-3); }
.panel--stack form > .button { align-self: flex-start; }
.panel__link { display: inline-flex; align-items: center; min-height: var(--tap); font-weight: 500; text-underline-offset: 3px; }
.panel + .form { margin-top: var(--space-5); }
.dp__date { display: flex; align-items: center; gap: var(--space-4); margin: 0 0 var(--space-4); font-weight: 500; font-size: var(--fs-lg); line-height: 1.25; }
.dp__week { color: var(--muted); font-weight: 400; white-space: nowrap; }
.dp__big { display: grid; place-items: center; flex: none; width: 2.1em; height: 2.1em; border-radius: 50%; background: var(--gold-light); color: var(--on-gold); font-size: var(--fs-2xl); line-height: 1; }
.dp__rows { list-style: none; margin: 0; padding: 0; }
.dp__row { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-1); padding: var(--space-3) 0; border-top: var(--hairline) solid var(--rule); }
.dp__when { font-weight: 600; font-variant-numeric: tabular-nums; }
.dp__clash { color: var(--danger); font-weight: 600; font-size: var(--fs-sm); }
.dp__foot { margin: var(--space-4) 0 0; }
.dp__close { display: none; }

/* The day drawer (from 960px, opened by app.js as a modal <dialog>). */
.drawer { position: fixed; inset: 0 0 0 auto; margin: 0; width: min(30rem, 100vw); max-width: none; height: 100dvh; max-height: none; padding: 0; border: 0; background: transparent; color: var(--ink); overflow: visible; }
.drawer::backdrop { background: var(--scrim); }
.drawer > .panel { position: relative; height: 100%; overflow-y: auto; border-radius: var(--radius-panel) 0 0 var(--radius-panel); padding: var(--space-6) var(--space-5); }
.drawer .dp__close { display: grid; place-items: center; position: absolute; top: var(--space-4); right: var(--space-4); width: var(--tap); height: var(--tap); border-radius: 50%; color: var(--ink); }
.drawer .dp__close:hover { background: var(--ground); }
.drawer .dp__date { padding-right: var(--tap); }
@media (prefers-reduced-motion: no-preference) {
  .drawer[open] { animation: drawer-in .2s ease-out; }
  .drawer[open]::backdrop { animation: fade-in .2s ease-out; }
}
@keyframes drawer-in { from { transform: translateX(100%); } }
@keyframes fade-in { from { opacity: 0; } }
