/*
  layout.css
  ----------
  Page-level structure for the real site: the fixed background layer,
  the top metal bar with logo and utility area, the three-column main
  content shell, and the footer. Built entirely from tokens.css and the
  locked components in components.css (dark cast metal, hairline gold
  trim, the .btn component) — no new colors are introduced here.

  This is the SHELL pass: proportions and structure only. The plain
  dashed .placeholder-box class stands in for every piece of real
  content (nav items, hero, news, features, quick links, screenshot of
  the day) — none of that gets its own material treatment yet. The
  structural chrome around it (top bar, content panel) already uses the
  real dark-metal/stone materials since those are locked and approved.
*/

/* ===================================================================
   Fixed full-viewport background layer
   =================================================================== */

.site-bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  background-color: var(--color-bg-void);

  /* To swap the background image, replace assets/screenshots/background.jpg
     (or update the filename below). Fixed to the viewport (doesn't scroll),
     background-size:cover crops to fill at any aspect ratio rather than
     stretching. */
  background-image: url('../assets/screenshots/background.jpg');
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.site-bg::after {
  /* Four adjustable layers, most localized first — tune via the --bg-*
     tokens in tokens.css, not here:
       1. an extra dark band behind where the content column sits, so
          the panel keeps contrast even if something bright in the
          image (the mist) falls right behind it
       2. extra darkening at the bottom edge specifically, where the
          footer sits — the center is untouched, only the bottom falls
          away harder than the general vignette below
       3. the general vignette — all edges fall away to near-black
       4. a flat darken over the whole image */
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(ellipse 640px 780px at 50% 38%, rgba(0, 0, 0, var(--bg-panel-darken)) 0%, transparent 70%),
    linear-gradient(to bottom, transparent 60%, rgba(0, 0, 0, var(--bg-vignette-bottom)) 100%),
    radial-gradient(ellipse at center, transparent 0%, rgba(0, 0, 0, var(--bg-vignette-strength)) 60%, rgba(0, 0, 0, 0.95) 100%);
  background-color: rgba(0, 0, 0, var(--bg-darken));
}


/* ===================================================================
   Top bar — narrow full-width cast metal bar, logo overlapping it,
   utility area (search + button) on the right
   =================================================================== */

.site-topbar {
  position: relative;
  width: 100%;
  height: 34px;
  background-image:
    var(--texture-rivet-tile),
    linear-gradient(180deg, var(--color-metal-rise) 0%, var(--color-metal-dark) 55%, var(--color-bronze-deepest) 100%);
  background-repeat: repeat, no-repeat;
  background-size: 14px 14px, 100% 100%;
  box-shadow:
    inset 0 1px 0 var(--color-gold-highlight),
    inset 0 -1px 0 var(--color-gold-highlight),
    0 4px 14px rgba(0, 0, 0, 0.55);
}

.site-topbar::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--texture-metal-noise);
  background-size: 130px 130px;
  opacity: var(--opacity-texture-metal);
  mix-blend-mode: overlay;
  pointer-events: none;
}

.site-topbar__inner {
  position: relative;
  height: 100%;
  max-width: var(--layout-width-wide);
  margin: 0 auto;
  padding: 0 var(--space-6);
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

/* Logo slot: no box, no border, no background — the real guild logo
   (assets/img/eldvik-logo.png, its own transparent cutout) hangs
   directly over the bar and the page background, sitting over the
   bar's left portion (roughly above where the nav column falls below).
   Pinned onto the bar rather than centered on it: only a small amount
   pokes above the top edge, most of its height hangs down over the
   content below — top is a fixed offset rather than 50%/translateY so
   that asymmetry is easy to tune (see the two numbers below). To swap
   the logo file later, just replace assets/img/eldvik-logo.png (or
   update the src below) — the fixed height and flex alignment mean the
   layout doesn't need to change as long as the new file also has a
   transparent background. */
.site-logo-slot {
  position: absolute;
  left: var(--space-6);
  top: -16px; /* how far it pokes above the bar's top edge */
  z-index: 2;
  height: 100px; /* -16px above + 100px tall = 50px hanging below a 34px bar */
  display: flex;
  align-items: center;
  pointer-events: none;
}

.site-logo-slot__img {
  height: 100%;
  width: auto;
  display: block;
  /* Layered glow, each following the logo's own alpha silhouette (not a
     box) — colors/radii are tokens in tokens.css, tune there. Two blue
     layers only (a third gold layer was muddying it into grey — see the
     comment in tokens.css), kept tight so it stays close to the logo. */
  filter:
    drop-shadow(0 var(--logo-glow-shadow-offset) var(--logo-glow-shadow-radius) var(--color-logo-glow-shadow))
    drop-shadow(0 0 var(--logo-glow-outer-radius) var(--color-logo-glow-outer))
    drop-shadow(0 0 var(--logo-glow-inner-radius) var(--color-logo-glow-inner));
}

.site-utility {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.site-utility__input {
  background: var(--color-metal-dark);
  border: 1px solid var(--color-gold-highlight);
  border-radius: var(--radius-sm);
  color: var(--color-text-on-dark);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  padding: var(--space-1) var(--space-2);
  box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.6);
  width: 130px;
}

.site-utility__input::placeholder {
  color: var(--color-text-on-dark-muted);
}

.site-utility__input:focus {
  outline: none;
  border-color: var(--color-ice-accent);
  box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(127, 168, 189, 0.25);
}

.site-utility .btn--compact {
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs);
}

/* Hamburger nav toggle — hidden by default (desktop). The narrow-
   screens media query at the end of this file is the only place it's
   made visible and fully styled; this is the one declaration for it
   that has to live outside that media query, since "hidden until
   proven narrow" has to be the default, not an override of it. */
.nav-toggle {
  display: none;
}


/* ===================================================================
   Main content — centered, ~1100px, flush against the top bar (no
   gap, no rounded corners), three columns sharing one dark stone body
   so they read as one panel. Framed in the same dark cast-metal band
   as the rest of the site (same recipe as .ornate-frame in
   components.css, recomposed here square-cornered and full-bleed on
   top rather than as a standalone rounded box) — components.css itself
   is untouched.
   =================================================================== */

.site-main {
  max-width: var(--layout-width-wide);
  margin: var(--space-4) auto var(--space-6);
  padding: 0 var(--space-5);
}

/* The metal band — square corners. Sits just below the top bar and the
   glow trim, with a small deliberate gap (site-main's top margin above)
   rather than touching the trim line. */
.site-panel-frame {
  position: relative;
  z-index: 0;
  background-image:
    var(--texture-rivet-tile),
    linear-gradient(180deg, var(--color-metal-rise) 0%, var(--color-metal-dark) 55%, var(--color-bronze-deepest) 100%);
  background-repeat: repeat, no-repeat;
  background-size: 14px 14px, 100% 100%;
  padding: var(--space-2);
  box-shadow:
    0 0 0 1px var(--color-gold-highlight),
    inset 1px 1px 0 var(--color-metal-rise),
    inset -1px -1px 0 var(--color-bronze-deepest),
    0 6px 18px rgba(0, 0, 0, 0.6);
}

.site-panel-frame::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--texture-metal-noise);
  background-size: 130px 130px;
  opacity: var(--opacity-texture-metal);
  mix-blend-mode: overlay;
  pointer-events: none;
}

/* The stone body held inside the band. */
.site-content-panel {
  position: relative;
  background: linear-gradient(160deg, var(--color-chrome-dark), var(--color-chrome-mid));
  box-shadow:
    0 0 0 1px var(--color-gold-highlight),
    inset 0 4px 10px rgba(0, 0, 0, 0.65);
  padding: var(--space-4);
}

.site-grid {
  display: grid;
  grid-template-columns: 180px minmax(0, 1fr) 230px;
  gap: var(--space-4);
  align-items: start;
}

.site-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}


/* ===================================================================
   Placeholder box — stands in for every piece of real content this
   pass. Plain and undecorated on purpose: the chrome around it (top
   bar, content panel) already carries the real materials; dressing
   these individual boxes is a later step.
   =================================================================== */

.placeholder-box {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  border: 1px dashed var(--color-text-on-dark-muted);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.02);
  color: var(--color-text-on-dark-muted);
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  padding: var(--space-1);
}


/* ===================================================================
   Nav link — flat, no sub-links, pressed-metal plates. Display font,
   uppercase, generous tracking, aged gold label. Hover is decisive
   (fast transition, no fade): the plate lightens, the label brightens
   to the ice-blue accent, the bevel highlight lifts. The active
   (current-page) state is inverted — recessed, as if pressed in —
   rather than just an outline.

   2026-09: reverted the octagon chamfer-plate rebuild entirely — the
   corner cut was too deep (read as arrow shapes) and the edge rivets
   were never asked for. Back to this box-shadow-bevel version, with
   one change: label font size increased noticeably (was too small to
   read comfortably).
   =================================================================== */

.site-nav-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.site-nav-link {
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  text-align: center;
  color: var(--color-gold);
  text-decoration: none;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.85); /* hard, no blur, so letters stay crisp */
  padding: var(--space-2) var(--space-3);
  border-radius: 0;
  background: linear-gradient(180deg, var(--color-metal-rise) 0%, var(--color-metal-dark) 55%, var(--color-bronze-deepest) 100%);
  box-shadow:
    0 0 0 1px var(--color-gold-highlight),
    inset 0 2px 0 var(--color-gold-highlight),   /* brighter, thicker top highlight */
    inset 0 -2px 0 var(--color-bronze-deepest),  /* deep bottom shadow */
    0 3px 6px rgba(0, 0, 0, 0.5);                 /* soft shadow cast onto the panel behind */
  transition: background 0.08s ease, color 0.08s ease, box-shadow 0.08s ease;
}

.site-nav-link:hover,
.site-nav-link:focus-visible {
  color: var(--color-ice-accent);
  background: linear-gradient(180deg, var(--color-metal-rise) 0%, var(--color-metal-rise) 45%, var(--color-metal-dark) 100%);
  box-shadow:
    0 0 0 1px var(--color-ice-accent),
    inset 0 2px 0 var(--color-gold-highlight),
    inset 0 -2px 0 var(--color-bronze-deepest),
    0 3px 6px rgba(0, 0, 0, 0.5);
  text-decoration: none;
}

/* Active nav item — the current page — pressed in, not just outlined:
   the highlight/shadow positions are swapped from the resting state. */
.site-nav-link.is-active {
  color: var(--color-ice-accent);
  background: linear-gradient(180deg, var(--color-bronze-deepest) 0%, var(--color-metal-dark) 100%);
  box-shadow:
    0 0 0 1px var(--color-ice-accent),
    inset 0 2px 0 var(--color-bronze-deepest),
    inset 0 -2px 0 rgba(255, 255, 255, 0.08),
    0 1px 2px rgba(0, 0, 0, 0.4);
}

/* Click/press feedback — the plate shifts down, highlight and shadow
   swap, so it feels physically pushed. Wins over both hover and
   is-active (comes last) since any plate should show a press. */
.site-nav-link:active {
  transform: translateY(1px);
  box-shadow:
    0 0 0 1px var(--color-gold-highlight),
    inset 0 2px 0 var(--color-bronze-deepest),
    inset 0 -2px 0 var(--color-gold-highlight),
    0 1px 2px rgba(0, 0, 0, 0.4);
}

/* Apply — same plate treatment, larger and warmer so it still stands
   apart from the four flat links above it (gap via margin-top). Warmer:
   brighter gold label, a gold-tinted (not ice-blue) hover. */
.site-nav-link--apply {
  margin-top: var(--space-3);
  font-size: var(--text-lg);
  padding: var(--space-3) var(--space-4);
  color: var(--color-gold-highlight);
  background: linear-gradient(180deg, var(--color-metal-rise) 0%, var(--color-gold-shadow) 55%, var(--color-bronze-deepest) 100%);
  box-shadow:
    0 0 0 1px var(--color-gold-highlight),
    inset 0 2px 0 var(--color-gold-highlight),
    inset 0 -2px 0 var(--color-bronze-deepest),
    0 4px 8px rgba(0, 0, 0, 0.55);
}

.site-nav-link--apply:hover,
.site-nav-link--apply:focus-visible {
  color: var(--color-gold-highlight);
  filter: brightness(1.25);
  box-shadow:
    0 0 0 1px var(--color-gold-highlight),
    inset 0 2px 0 var(--color-gold-highlight),
    inset 0 -2px 0 var(--color-bronze-deepest),
    0 4px 8px rgba(0, 0, 0, 0.55);
  text-decoration: none;
}

.site-nav-link--apply:active {
  filter: none;
  transform: translateY(1px);
  box-shadow:
    0 0 0 1px var(--color-gold-highlight),
    inset 0 2px 0 var(--color-bronze-deepest),
    inset 0 -2px 0 var(--color-gold-highlight),
    0 1px 2px rgba(0, 0, 0, 0.4);
}


/* ===================================================================
   Side box — a small framed box for the nav column (Status) and the
   right column (Links): dark stone fill, hairline gold ring, plain
   label/value or link rows. Same material as .site-nav-link, no
   heading required (Status has none; Links uses .side-box__heading).
   =================================================================== */

.side-box {
  background: linear-gradient(160deg, var(--color-chrome-dark), var(--color-chrome-mid));
  border-radius: var(--radius-sm);
  box-shadow: 0 0 0 1px var(--color-gold-highlight);
  padding: var(--space-3);
}

.side-box__heading {
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  color: var(--color-gold-highlight);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding-bottom: var(--space-2);
  margin-bottom: var(--space-2);
  border-bottom: var(--border-thin) solid var(--color-chrome-highlight);
}

.side-box__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-2) 0;
  font-family: var(--font-body);
  font-size: var(--text-sm);
}

.side-box__label {
  color: var(--color-text-on-dark-muted);
}

.side-box__value {
  color: var(--color-text-on-dark);
  text-align: right;
}

.side-box__link {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--color-link);
  text-decoration: none;
  padding: var(--space-2) 0;
}

.side-box__link:hover,
.side-box__link:focus-visible {
  color: var(--color-link-hover);
  text-decoration: underline;
}


/* ===================================================================
   Hero banner — a cropped screenshot with a short line of text and a
   button over it, darkened so the text stays readable regardless of
   the image.

   2026-09: real image (assets/img/home-banner.png — a valley/river/
   mountain vista, resized to 1200px wide and palette-quantized for web
   use before copying in). Kept dimensions/border/corner/position exactly
   as they were — only background-image and background-position changed
   on .hero-banner itself.

   The source photo is very bright (white sky, strong sun on the right)
   with the text/button sitting over the lower-left corner, so the old
   uniform top-to-bottom ::before darkening (built for the old stand-in
   image) is replaced with a corner-anchored radial fade: darkest at the
   bottom-left, fading out toward the top and right so the sky and sunlit
   areas stay bright — a gradual fade, not a band. Opacity verified by
   sampling the actual rendered pixels behind the hero text and button
   (canvas + WCAG contrast math) — see the values below and the report
   given alongside this change. */

.hero-banner {
  position: relative;
  height: 220px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  box-shadow: 0 0 0 1px var(--color-gold-highlight);
  background-image: url('../assets/img/home-banner.png');
  background-size: cover;
  background-position: center;
}

.hero-banner::before {
  content: "";
  position: absolute;
  inset: 0;
  /* Fixed px radii (not %) on purpose: the banner's height is constant
     (220px) but its width is fluid with the browser window (this site
     has no responsive breakpoints) — a percentage-sized ellipse would
     shrink at narrower widths and under-cover the text/button exactly
     where the darkening matters most. Sized to the current text/button.
     2026-09: the button reverted from the Ansök gold-plate styling back
     to plain .btn, and the text sits a little lower/tighter above it as
     a result (no margin-top of its own) — re-verified against that new,
     slightly more compact position; 500/400 already covered it with
     good margin at both the widest (562px) and narrowest reasonable
     (297px) column widths, so left as-is rather than shrinking further
     and risking under-coverage at the narrow end. See the contrast
     report alongside this change. */
  background: radial-gradient(ellipse 500px 400px at 0% 100%,
    rgba(0, 0, 0, 0.9) 0%,
    rgba(0, 0, 0, 0.7) 45%,
    rgba(0, 0, 0, 0.42) 75%,
    transparent 110%
  );
}

.hero-banner__content {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  gap: var(--space-3);
  padding: var(--space-4);
}

.hero-banner__text {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  color: var(--color-text-on-dark);
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.9);
  margin: 0;
}


/* ===================================================================
   News entry — ONE .parchment-panel per entry (article carries both
   classes), so the locked texture and edge-darkening apply once, not
   twice. 2026-09 v4: dropped the separate gradient-wash div from v3 —
   it was inset within the header's own padding and stopped short of
   the panel edges, reading as a pale rectangle rather than a tone
   shift. No rule, no separate layer — just spacing before the body
   text starts.
   =================================================================== */

.news-entry__header {
  margin: 0 0 var(--space-2);
}

.news-entry__title {
  font-size: var(--text-lg); /* smaller than the default h3 — long titles
    were wrapping to two lines at this column width */
  margin: 0;
}

.news-entry__header a {
  color: var(--color-parchment-link);
  text-decoration: none;
}

.news-entry__header a:hover,
.news-entry__header a:focus-visible {
  color: var(--color-parchment-link-hover);
  text-decoration: underline;
}

.news-entry__byline {
  font-family: var(--font-heading);
  font-size: var(--text-xs);
  color: var(--color-parchment-edge);
  margin: var(--space-1) 0 0;
}

/* Body text darkened for contrast against the current (darker)
   parchment tone — targets only the entry's own body paragraph
   (a direct child of .news-entry), not the byline. */
.news-entry > p {
  color: var(--color-parchment-text-dark);
}


/* ===================================================================
   About page panel titles — same colour and size as the news post
   titles on index.html. Scoped to this extra class (not to the shared
   .news-entry__title) so index.html is never touched: these titles
   aren't wrapped in <a> like the news posts are, so they need the
   link color applied directly rather than picked up from an anchor.
   Values copied as-is from .heading-rule / .heading-rule::after in
   components.css (components.css itself is untouched) for the rule
   line under each title — same colour, thickness and gradient shape.
   =================================================================== */

/* .parchment-panel .about-panel-title (not just .about-panel-title) is
   needed to outweigh the locked ".parchment-panel h1..h6" color rule in
   components.css, which is more specific than a single class alone. */
.parchment-panel .about-panel-title {
  position: relative;
  color: var(--color-parchment-link);
  padding-bottom: var(--space-2);
}

.about-panel-title::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg,
    transparent 0%,
    var(--color-gold) 15%,
    var(--color-gold-highlight) 50%,
    var(--color-gold) 85%,
    transparent 100%
  );
}

/* Extra top margin on top of .site-col's own flex gap (--space-2, 8px)
   — adds --space-1 (4px) to reach 12px, roughly 1.5x — between the
   intro panel and "What you'll find here", that heading and the first
   panel, and between each of the four panels. Scoped to this class
   (not the shared .site-col gap) so index.html's spacing is untouched. */
.about-extra-gap {
  margin-top: var(--space-1);
}


/* ===================================================================
   Recruitment fact grid — four .side-box boxes (same dark-metal/gold-
   hairline styling as the status box, and the same .side-box__label /
   .side-box__value classes — colour, size, weight, letter-spacing all
   unchanged) arranged two per row. Label sits above value here rather
   than side by side (<div> instead of <span> for the block stacking).
   Alignment/spacing below is scoped to .recruitment-facts specifically
   so the status box's own label-left/value-right row layout, shared
   from the same .side-box__value rule, is untouched everywhere else.
   =================================================================== */

.recruitment-facts {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
}

.recruitment-facts .side-box__label {
  margin-bottom: var(--space-1);
}

.recruitment-facts .side-box__value {
  text-align: left;
}


/* ===================================================================
   Roles grid — inside a plain .parchment-panel (locked, untouched),
   four role rows two per row: a round icon, the role name (reusing
   .side-box__label, just at normal body text size), and a status word
   pushed to the right edge. Read-only — plain text, nothing clickable.
   =================================================================== */

.roles-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}

.role-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* Shared sizing/shape so the inline SVG (Social) doesn't look out of
   place next to the three PNGs — all four render at the same size,
   same round shape. */
.role-row__icon {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  display: block;
  border-radius: 50%;
  object-fit: contain;
}

.role-row__name {
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--color-parchment-text);
}

.role-row__status {
  margin-left: auto;
  font-family: var(--font-body);
  font-size: var(--text-sm);
}

.role-row__status--open {
  color: var(--color-status-open);
}

.role-row__status--closed {
  color: var(--color-status-closed);
}


/* ===================================================================
   FAQ — native <details>/<summary>, no JavaScript. Question styling
   duplicates the role name treatment (same colour/font/weight, not the
   class itself, to keep this self-contained); the answer <p> needs no
   extra CSS at all — it's an ordinary descendant of .parchment-panel,
   so the locked .parchment-panel p rule already styles it. The rule
   between items is the same fading-gradient line used under headings
   (.heading-rule::after) and the about-page panel titles, copied as
   values, not shared via class. The disclosure triangle is replaced
   with a plus/minus drawn from two background gradients on one
   pseudo-element, swapped by the browser's own [open] state — no JS.
   =================================================================== */

.faq-item {
  margin: 0;
  padding: 0;
}

.faq-item:not(:last-of-type) {
  position: relative;
  margin-bottom: calc(var(--space-3) * 2);
}

.faq-item:not(:last-of-type)::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: calc(-1 * var(--space-3) - 1px);
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg,
    var(--color-gold) 0%,
    var(--color-gold-highlight) 50%,
    var(--color-gold) 100%
  );
}

.faq-item p {
  margin-top: var(--space-2);
}

.faq-question {
  position: relative;
  display: block;
  list-style: none; /* removes the default marker in Firefox */
  cursor: pointer;
  padding: var(--space-2) var(--space-6) var(--space-2) 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--color-parchment-text);
}

.faq-question::-webkit-details-marker {
  display: none; /* removes the default marker in Chrome/Safari */
}

.faq-question:hover {
  color: var(--color-gold);
}

/* Plus/minus, drawn from two background gradients (a vertical bar and
   a horizontal bar) on one pseudo-element; [open] drops to one
   gradient, leaving just the horizontal bar as a minus sign. */
.faq-question::after {
  content: "";
  position: absolute;
  top: 50%;
  right: var(--space-3);
  width: 14px;
  height: 14px;
  transform: translateY(-50%);
  background-image:
    linear-gradient(var(--color-parchment-text), var(--color-parchment-text)),
    linear-gradient(var(--color-parchment-text), var(--color-parchment-text));
  background-size: 2px 14px, 14px 2px;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
}

.faq-item[open] .faq-question::after {
  background-image: linear-gradient(var(--color-parchment-text), var(--color-parchment-text));
  background-size: 14px 2px;
}


/* ===================================================================
   Raid card — dark metal panel (reuses .side-box directly for the
   material: same border, corner radius, hairline gold ring, padding —
   no new panel style invented). Title colour is deliberately NOT
   --color-parchment-link even though that's the news-post-title colour
   elsewhere: that token was picked for the light parchment panels and
   computes to ~1.7:1 contrast on this dark chrome (near-invisible), so
   --color-gold-highlight is used instead — the token already used for
   other titles/headings on dark chrome (.side-box__heading below), at
   ~10:1. Confirmed with the site owner before building. Rule under the
   title copies .heading-rule::after's values (same fading gradient, not
   the shared class, matching the project's usual pattern). Stats row
   reuses .side-box__label/.side-box__value directly and duplicates
   .recruitment-facts' label-above-value/left-align values under its own
   scoped selector, same reasoning.

   Background image + overlay (2026-09, replaces the progress meter):
   each card gets its own scene behind the text via a --card-image
   custom property (set per raid in a .raid-card--* modifier below,
   alongside its own --card-image-position so the most relevant part of
   each picture stays in frame). It's painted on ::before, kept behind
   .side-box's own chrome gradient is no longer visible since ::before
   sits above it but below the text (both pseudo-elements carry negative
   z-index within .raid-card's own local stacking context, so they never
   compete with the card's own content) — .raid-card gets overflow:hidden
   so the image is clipped to the card's existing corner radius rather
   than squaring it off. A shared slight desaturation via filter on the
   image layer keeps the scenes in the same muted colour family as the
   rest of the site rather than reading as saturated photos.

   2026-09, text anchored to the top/bottom edges: the title sits at the
   card's top edge and the description+stats sit at its bottom edge (see
   .raid-card__bottom below), leaving the middle of the card as open
   image — .raid-card is a fixed-height flex column with
   justify-content:space-between doing that split; see the height
   comment just above the rule for how that number was derived. ::after
   darkens the two text bands (0-16.7% and 62.1-100% of the card's
   height, matching where the title and bottom blocks actually sit) at
   the full --card-overlay strength, fading over a short feather to 55%
   of that strength across the open middle, so the centre stays as clear
   as the fade allows while the top/bottom edges keep exactly the same
   opacity the flat version used to (still driven by --color-chrome-dark,
   the same dark surface token the plain side-box material is built
   from, via color-mix() rather than a hardcoded rgb() so it keeps
   tracking that token). --card-overlay stays the one number per card to
   tune — Hyjal Summit is set noticeably higher than the other two since
   its source photo is much brighter/warmer. Contrast (title/label/value
   against the actual rendered pixels behind them, sampled across each
   text area) was reverified after this restructure, not assumed from
   the previous flat-overlay numbers — see the values on each <article>
   in progression.html. No border glow or other decorative treatment
   beyond this edge darkening was added. */

/* 264px = the measured title-block height (32px) + bottom-block height
   (88px) + the card's own 12px top/bottom padding, with the leftover
   (120px, handed to justify-content:space-between below) equal to that
   same 32+88=120px combined text-block height — i.e. the open image
   band in the middle reads at roughly the height of the two text blocks
   put together, per spec. Recompute this by hand (measure
   .raid-card__title and .raid-card__bottom with the height rule below
   removed) if the card copy or fonts ever change enough to shift those
   two numbers. */
.raid-card {
  position: relative;
  z-index: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 264px;
}

/* Groups the description + stats row so they move as one unit anchored
   to the card's bottom edge (.raid-card's own justify-content:
   space-between pushes .raid-card__title to the top and this group to
   the bottom, leaving the space between them — sized via .raid-card's
   own height below — as open image). Internal gap matches the value
   .raid-card itself used to apply between all three children before
   this split, so the paragraph-to-stats spacing is unchanged. */
.raid-card__bottom {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.raid-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background-image: var(--card-image);
  background-size: cover;
  background-position: var(--card-image-position, center);
  filter: saturate(0.75);
}

/* Edge-darkened overlay (2026-09, replaces the old flat tint): text now
   lives in two bands, one hugging the top edge (the title, 0-16.7% of
   the card) and one hugging the bottom edge (description + stats,
   62.1-100%) — see the height comment above for where those percentages
   come from. --card-overlay is still the single per-card number to tune
   (kept exactly as the opacity behind the text, so an existing
   contrast-verified value keeps meaning the same thing), full-strength
   across each text band, fading over a ~20px feather to 55% of that
   strength across the open middle so the clear image band reads as
   clearly as the fade allows while the ends stay subtle rather than a
   hard-edged stripe.

   2026-09 fix: this was first built with color-mix(in srgb,
   var(--color-chrome-dark) calc(...), transparent) for each stop, which
   rendered as a visible hard band instead of a smooth fade in at least
   one browser (calc() driving a percentage inside color-mix() inside a
   gradient stop is a fairly new/rare combination, and support for
   interpolating smoothly between two such stops isn't reliable yet).
   Replaced with plain rgba() and calc() only on the alpha channel — much
   older, near-universally supported — using --color-chrome-dark's own
   rgb(20, 22, 28) written out literally, since rgba() can't pull that
   apart from the hex token itself; the color is still exactly that
   token, just expressed in the syntax rgba() requires. */
.raid-card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to bottom,
    rgba(20, 22, 28, calc(var(--card-overlay, 0.85) * 1)) 0%,
    rgba(20, 22, 28, calc(var(--card-overlay, 0.85) * 1)) 16.7%,
    rgba(20, 22, 28, calc(var(--card-overlay, 0.85) * 0.55)) 24.2%,
    rgba(20, 22, 28, calc(var(--card-overlay, 0.85) * 0.55)) 54.5%,
    rgba(20, 22, 28, calc(var(--card-overlay, 0.85) * 1)) 62.1%,
    rgba(20, 22, 28, calc(var(--card-overlay, 0.85) * 1)) 100%
  );
}

.raid-card--barrow-deeps {
  --card-image: url('../assets/img/barrow-deeps.png');
  --card-image-position: center 75%;
}

.raid-card--hyjal-summit {
  --card-image: url('../assets/img/hyjal-summit.png');
  --card-image-position: center 100%;
}

.raid-card--onyxia {
  --card-image: url('../assets/img/onyxia.jpg');
  --card-image-position: center center;
}

/* Card-to-card spacing only (not panel-to-first-card, which stays at
   the plain .site-col gap, matching recruitment.html's block rhythm) —
   adds the same extra var(--space-1) on top of that gap that
   .about-extra-gap uses between panels on about.html, reaching the same
   12px total, but scoped via adjacent-sibling so only the 2nd/3rd cards
   pick it up. */
.raid-card + .raid-card {
  margin-top: var(--space-1);
}

.raid-card__title {
  position: relative;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-lg); /* matches .news-entry__title — a card title, not a page heading */
  color: var(--color-gold-highlight);
  padding-bottom: var(--space-2);
}

.raid-card__title::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg,
    transparent 0%,
    var(--color-gold) 15%,
    var(--color-gold-highlight) 50%,
    var(--color-gold) 85%,
    transparent 100%
  );
}

.raid-card__stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
}

.raid-card__stats .side-box__label {
  margin-bottom: var(--space-1);
}

.raid-card__stats .side-box__value {
  text-align: left;
}


/* ===================================================================
   Gallery grid — galleri.html. Three thumbnails per row, each a plain
   .side-box (the same dark-metal/hairline-gold material as the
   recruitment fact boxes — reused directly, not a new panel style)
   holding a cropped image and its caption. aspect-ratio + object-fit:
   cover crop every image to the same shape regardless of its own
   source proportions, so the grid stays even.

   Each .gallery-item is a real <button> (js/gallery-data.js), not a
   styled div, so it gets keyboard focus/activation for free — the
   rules below just undo the browser's own default button chrome
   (border, text alignment, font) so it reads as a plain panel like
   every other .side-box, plus a hover/focus glow using the same
   --shadow-glow-gold token .btn already uses on hover, as the only
   visual sign it's clickable (opens js/gallery-lightbox.js).
   =================================================================== */

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-2);
}

.gallery-item {
  display: block;
  width: 100%;
  border: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.gallery-item:hover,
.gallery-item:focus-visible {
  box-shadow: 0 0 0 1px var(--color-gold-highlight), var(--shadow-glow-gold);
}

.gallery-item__image {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-sm);
  box-shadow: 0 0 0 1px var(--color-gold-highlight);
  margin-bottom: var(--space-2);
}

.gallery-item__caption {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-on-dark);
  margin: 0;
}


/* ===================================================================
   Gallery lightbox — built entirely by js/gallery-lightbox.js (kept
   out of every page's HTML so the markup exists once, not once per
   page). Reuses the site's existing dark cast-metal gradient (the
   same recipe as .btn/.site-nav-link) for the frame and controls, the
   hairline gold ring (--color-gold-highlight) everywhere the rest of
   the site uses it, and --color-bg-void (the page's own outermost
   background colour) for the backdrop — no colour here is new.
   =================================================================== */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
}

.lightbox[hidden] {
  display: none;
}

.lightbox__backdrop {
  position: absolute;
  inset: 0;
  background-color: var(--color-bg-void);
  opacity: 0.92;
}

.lightbox__content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  max-width: min(92vw, 1400px);
  max-height: 92vh;
  min-height: 0;
}

.lightbox__frame {
  position: relative;
  display: flex;
  min-height: 0;
  background: linear-gradient(160deg, var(--color-chrome-dark), var(--color-chrome-mid));
  box-shadow: 0 0 0 1px var(--color-gold-highlight), var(--shadow-panel);
  border-radius: var(--radius-sm);
  padding: var(--space-2);
}

.lightbox__image {
  display: block;
  max-width: 100%;
  max-height: calc(92vh - 120px);
  border-radius: var(--radius-sm);
  object-fit: contain;
}

.lightbox__caption {
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--color-text-on-dark);
  text-align: center;
  margin: 0;
  max-width: 100%;
}

.lightbox__close,
.lightbox__nav {
  position: absolute;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  padding: 0;
  cursor: pointer;
  background: linear-gradient(180deg, var(--color-metal-rise) 0%, var(--color-metal-dark) 55%, var(--color-bronze-deepest) 100%);
  color: var(--color-gold-highlight);
  box-shadow: 0 0 0 1px var(--color-gold-highlight);
}

.lightbox__close:hover,
.lightbox__close:focus-visible,
.lightbox__nav:hover,
.lightbox__nav:focus-visible {
  color: var(--color-ice-accent);
  box-shadow: 0 0 0 1px var(--color-ice-accent);
}

.lightbox__close svg,
.lightbox__nav svg {
  width: 40%;
  height: 40%;
}

.lightbox__close {
  top: var(--space-4);
  right: var(--space-4);
  width: 48px;
  height: 48px;
  border-radius: var(--radius-round);
}

.lightbox__nav {
  top: 50%;
  transform: translateY(-50%);
  width: 48px;
  height: 48px;
  border-radius: var(--radius-round);
}

.lightbox__nav[hidden] {
  display: none;
}

.lightbox__nav--prev {
  left: var(--space-4);
}

.lightbox__nav--next {
  right: var(--space-4);
}


/* ===================================================================
   Screenshot frame — sits inside a .side-box (right column). The image
   itself is now the newest data/content.json "gallery" entry
   (js/screenshots.js), and the frame is a link to galleri.html — the
   hover/focus rule below is the only visual difference from before;
   the resting appearance is unchanged, and reuses the same
   --shadow-glow-gold hover token as .gallery-item and .btn, no new
   colour.
   =================================================================== */

.screenshot-frame {
  display: block;
  border-radius: var(--radius-sm);
  overflow: hidden;
  box-shadow: 0 0 0 1px var(--color-gold-highlight);
  aspect-ratio: 4 / 3;
  background: var(--color-metal-dark);
}

.screenshot-frame:hover,
.screenshot-frame:focus-visible {
  box-shadow: 0 0 0 1px var(--color-gold-highlight), var(--shadow-glow-gold);
}

.screenshot-frame__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}


/* ===================================================================
   Search results — js/search.js renders each result as a
   .parchment-panel.news-entry, identical to a news post (that pattern
   is untouched, reused as-is), so the only new rule needed here is the
   <mark> it wraps the matched term in. Dark parchment text on the
   existing gold hairline colour, the same pairing already used for
   this site's small accent shapes elsewhere — no new colour.
   =================================================================== */

.news-entry mark {
  background-color: var(--color-gold-highlight);
  color: var(--color-parchment-text-dark);
  border-radius: var(--radius-sm);
}


/* ===================================================================
   Application form (ansok.html) — fields sit directly on the
   parchment panel, so unlike .site-utility__input (light text on a
   dark field, for the dark top bar) these need the opposite polarity:
   dark parchment ink on a light field. --color-text-on-dark (already
   used elsewhere as a light warm-off-white) doubles as that light
   field colour here; the ink reuses --color-parchment-text, the same
   colour the rest of the panel's own text uses. Border and focus ring
   follow the exact same recipe as .site-utility__input — hairline
   gold at rest, --color-ice-accent + its glow ring on :focus — just
   recoloured for a light field instead of a dark one. No new colours.

   An invalid field's border and its error message both switch to
   --color-status-closed (already used elsewhere for a "closed/
   negative" state, and per tokens.css already contrast-checked
   against parchment) — reinforcement only: the message text itself
   ("Fel: ...") is what actually says what's wrong, so nothing here
   depends on colour alone to communicate the error.
   =================================================================== */

.application-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.application-form__required-note {
  font-size: var(--text-sm);
  font-style: italic;
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.form-field__label {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-parchment-text);
}

/* Toggled by js/ansok.js alongside aria-invalid — same
   --color-status-closed token as the error message/border, reinforcing
   which field the message below belongs to. The message text itself is
   still what actually says what's wrong. */
.form-field__label--error {
  color: var(--color-status-closed);
}

.form-field__input {
  background: var(--color-text-on-dark);
  border: 1px solid var(--color-gold-highlight);
  border-radius: var(--radius-sm);
  color: var(--color-parchment-text);
  font-family: var(--font-body);
  font-size: var(--text-base);
  padding: var(--space-2) var(--space-3);
  box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.25);
  width: 100%;
}

.form-field__textarea {
  resize: vertical;
  min-height: 6em;
}

.form-field__input:focus {
  outline: none;
  border-color: var(--color-ice-accent);
  box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.25), 0 0 0 2px rgba(127, 168, 189, 0.25);
}

.form-field__input[aria-invalid="true"] {
  border-color: var(--color-status-closed);
}

.form-field__error {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-status-closed);
  min-height: 1.2em;
}

.form-field__error:empty {
  display: none;
}

.application-form__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* The submit button's "filled gold" look: the exact same swap already
   used for .site-nav-link--apply (the warm/gold Ansök nav plate) —
   the dark-metal middle gradient stop becomes --color-gold-shadow
   instead of --color-metal-dark, nothing else about .btn changes, so
   its shape, padding, border, and hover/active/focus behaviour are
   all still the one existing .btn component, just recoloured. */
.btn--gold {
  background:
    radial-gradient(ellipse at 22% 78%, rgba(0, 0, 0, 0.25) 0%, transparent 45%),
    radial-gradient(ellipse at 85% 20%, rgba(255, 255, 255, 0.05) 0%, transparent 40%),
    linear-gradient(135deg,
      var(--color-metal-rise) 0%,
      var(--color-gold-shadow) 40%,
      var(--color-gold-shadow) 65%,
      var(--color-bronze-deepest) 100%
    );
}

/* The "Ansök via Discord" button is an <a class="btn"> sitting inside
   a .parchment-panel. .parchment-panel a's underline and blue link
   colour (components.css, meant for plain body-copy links) are both
   more specific than .btn's own styling, so they win over it — but
   --color-accent-blue is tuned for parchment, not a dark plate: only
   ~2.5:1 against this button's background, well under the 4.5:1 text
   needs. --color-ice-accent is reused instead — it's already the
   site's lighter, established blue-toned text colour for dark
   surfaces (site-nav-link hover, input focus, etc.), and at ~7:1
   against this button's background comfortably clears 4.5:1 while
   still reading unmistakably blue. Scoped to a.btn specifically so
   this only ever affects a link styled as a button, never an ordinary
   parchment-panel text link; one colour for every state (rest, hover,
   focus-visible) rather than swapping shades between them. */
.parchment-panel a.btn,
.parchment-panel a.btn:hover,
.parchment-panel a.btn:focus-visible {
  text-decoration: none;
  color: var(--color-ice-accent);
}


/* ===================================================================
   Footer
   =================================================================== */

.site-footer {
  padding: var(--space-6) var(--space-5);
  text-align: center;
}

.site-footer__disclaimer {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  line-height: var(--leading-relaxed);
  color: var(--color-text-on-dark-muted);
  max-width: 640px;
  margin: 0 auto;
}


/* ===================================================================
   Narrow screens (max-width: 900px) — the only place the three-column
   .site-grid changes shape; every rule the site otherwise relies on
   (column widths, the top bar, the nav's own styling, the metal
   treatment, the parchment) is untouched above this breakpoint and
   inside it alike, since nothing here overrides any of that — this
   block only ever sets grid-template-columns, order and padding.

   .site-col--nav's own box is dissolved (display: contents) so its
   two children, the nav list and the status box, can each be given
   their own grid "order" and stack independently — the status box has
   to land AFTER the main content column here even though it's still
   written before it in every page's HTML, and "order" is how that's
   done without moving it in the markup. .site-col--center and
   .site-col--right stay as single grid items (nothing inside either
   one needs reordering), so only their own "order" is set.

   2026: also where the hamburger toggle (#nav-toggle, js/nav-
   toggle.js) is shown and fully styled, and where #primary-nav (the
   same .site-nav-list promoted above) is hidden until
   js/nav-toggle.js adds .is-nav-open to it — it's still the very
   first item in the stacked column (order: 1 above), so expanding it
   already lands directly under the top bar and pushes everything
   after it down, with no extra positioning needed here.
   =================================================================== */

@media (max-width: 900px) {

  .site-grid {
    grid-template-columns: 1fr;
  }

  .site-col--nav {
    display: contents;
  }

  .site-col--nav > .site-nav-list {
    order: 1;
    display: none;
  }

  .site-col--nav > .site-nav-list.is-nav-open {
    display: flex;
  }

  .site-col--center {
    order: 2;
  }

  .site-col--nav > .side-box {
    order: 3;
  }

  .site-col--right {
    order: 4;
  }

  /* Same fixed gutters as above 900px, just smaller — at a phone width
     the full-size ones (space-5 outside, space-4 inside) leave very
     little room for actual content. */
  .site-main {
    padding: 0 var(--space-2);
  }

  .site-content-panel {
    padding: var(--space-2);
    overflow-wrap: break-word;
  }

  /* The search field shrinks instead of wrapping to a new line once
     the hamburger button below also needs room in the same row — the
     input's min-width:auto default (its own placeholder text's
     intrinsic width) is what would otherwise force a wrap, so that's
     overridden to 0 here; the button next to it keeps its own size
     rather than also shrinking illegibly. */
  .site-utility {
    min-width: 0;
    flex: 1 1 auto;
  }

  .site-utility__input {
    width: auto;
    min-width: 0;
    flex: 1 1 auto;
  }

  .site-utility .btn--compact {
    flex-shrink: 0;
  }

  /* Small version of the same dark cast-metal + hairline-gold plate
     .btn uses (135deg metal-rise/metal-dark/bronze-deepest gradient,
     1px gold-highlight border) rather than a new button design; the
     three lines reuse --color-gold-highlight too, the same colour
     .btn itself labels its text with. 44x44 is the minimum comfortable
     tap size. */
  .nav-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 44px;
    height: 44px;
    padding: 0;
    color: var(--color-gold-highlight);
    background:
      radial-gradient(ellipse at 22% 78%, rgba(0, 0, 0, 0.25) 0%, transparent 45%),
      radial-gradient(ellipse at 85% 20%, rgba(255, 255, 255, 0.05) 0%, transparent 40%),
      linear-gradient(135deg,
        var(--color-metal-rise) 0%,
        var(--color-metal-dark) 40%,
        var(--color-metal-dark) 65%,
        var(--color-bronze-deepest) 100%
      );
    border: 1px solid var(--color-gold-highlight);
    border-radius: var(--radius-sm);
    cursor: pointer;
  }

  .nav-toggle:hover,
  .nav-toggle:focus-visible {
    color: var(--color-ice-accent);
    border-color: var(--color-ice-accent);
  }

  .nav-toggle svg {
    width: 60%;
    height: 60%;
  }

  .nav-toggle svg line {
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
  }

  /* Gallery grid (galleri.html) — two thumbnails per row instead of
     three; everything else about .gallery-item is untouched. */
  .gallery-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  /* Gallery lightbox (js/gallery-lightbox.js) on touch screens. The
     existing min(92vw, 1400px)/92vh caps on .lightbox__content already
     keep the image within the screen at any width — only what's
     mobile-specific changes here:
       - smaller outer padding on .lightbox, so a phone-width screen
         isn't spending as much of its limited space on that margin
       - dvh instead of vh for the height caps, since a plain vh unit
         is the *maximum* viewport height with mobile browser chrome
         (address bar/toolbar) hidden — dvh tracks the actually-visible
         height, chrome shown or not, so the frame/image never end up
         taller than what's really on screen
       - the close control's own position gets env(safe-area-inset-*)
         added on top of its normal offset, so it clears a notch or
         any reserved browser-UI area instead of sitting under it;
         falls back to the same position as before where that env()
         isn't supported (defaults to 0) */
  .lightbox {
    padding: var(--space-3);
  }

  .lightbox__content {
    max-height: 92dvh;
  }

  .lightbox__image {
    max-height: calc(92dvh - 120px);
  }

  .lightbox__close {
    top: calc(var(--space-3) + env(safe-area-inset-top, 0px));
    right: calc(var(--space-3) + env(safe-area-inset-right, 0px));
  }

  /* Application form (ansok.html) on touch screens — comfortable tap
     targets and a full-width submit button; sizes/positions only, no
     new colours or panel styling. */
  .form-field__input {
    min-height: 44px;
    max-width: 100%;
  }

  .application-form__actions .btn--gold {
    width: 100%;
  }

}
