/* ---------- Nav ---------- */
[data-nav] {
  position: sticky;
  top: 0;
  z-index: 20;
  /* --paper at 92% — see tokens.css's --paper-rgb for why a triplet and
     not color-mix(). A literal here left the nav light on the "Mørk"
     palette's dark page. */
  background: rgba(var(--paper-rgb), 0.92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--s18) var(--page-x);
}

.wordmark {
  font-family: var(--serif);
  font-weight: 700;
  font-size: 19px;
  letter-spacing: 0.01em;
  display: flex;
  align-items: center;
}

/* Only present when the logo-image theme setting is uploaded — see
   partials/nav.html.twig. Height is the one setting exposed for it
   (logo-height, default 36px); width follows automatically so an
   unusually tall upload never distorts, and the blueprint's own
   16-56px validation range keeps the sticky ~62px nav bar from being
   forced open even on a 375px phone. */
.wordmark-logo {
  display: block;
  height: var(--logo-height, 36px);
  width: auto;
}

.nav-panel {
  display: flex;
  align-items: center;
  gap: 30px;
}

.nav-link {
  position: relative;
  font-size: 12px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

/* The nav looked identical on every route — nothing said which page you
   were on. A 1px rule under the current item reuses the underline
   vocabulary the theme already speaks in (.link-rule, .kontakt-email,
   .hero-eyebrow-rule) and, being a shape rather than a tint, does not lean
   on colour alone. nav.html.twig sets the matching aria-current="page" so
   assistive tech gets the same fact. */
.nav-link[aria-current='page']::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(var(--s6) * -1);
  height: 1px;
  background: var(--ink);
}

.lang-switch {
  display: flex;
  align-items: center;
  gap: 8px;
  border-left: 1px solid var(--rule);
  padding-left: var(--s26);
  font-size: 11px;
  letter-spacing: 0.18em;
}
/* Task 15: was var(--label) (2.49:1 on paper, fails WCAG AA's 4.5:1). Unlike
   the footer, this is a clickable control a visitor must read to find the
   English version, so it gets the same AA-passing tone as every other
   informational label (--muted, 5.04:1) rather than keeping the softer
   decorative one. */
.lang { color: var(--muted); }
.lang.is-active { color: var(--ink); }
.lang-sep { color: var(--rule); }

/* Hidden until the ≤900 breakpoint in responsive.css */
.nav-toggle { display: none; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- Footer ---------- */
.site-footer {
  border-top: 1px solid var(--rule);
  padding: var(--s26) var(--page-x);
  display: flex;
  justify-content: space-between;
  gap: var(--s26);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  /* Was var(--label) — 2.49:1 on paper, against WCAG AA's 4.5:1 for 10px
     text — kept deliberately, and excluded from the axe scan, on the
     grounds that the footer only repeats what the page already says. That
     holds on the Forside, whose eyebrow is the same "Skuespiller ·
     København" string, and nowhere else: on /om, /projekter, /galleri and
     /kontakt this line is the only place the role and city appear at all.
     Same reasoning and same tone as the language switch above; the axe
     exclusion in tests/a11y.spec.ts is gone with it. --label survives for
     genuinely decorative marks that carry no information of their own
     (.prose li::marker). */
  color: var(--muted);
}

/* ---------- Page shells ---------- */
.page-shell {
  padding: var(--page-y) var(--page-x);
  display: flex;
  flex-direction: column;
  gap: var(--s44);
}

/* ---------- Buttons ---------- */
.btn {
  padding: var(--s14) var(--s26);
  font-size: 11.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  display: inline-block;
}
.btn-solid { background: var(--ink); color: var(--paper); }
.btn-solid:hover { background: var(--ink-soft); color: var(--paper); }
.btn-outline { border: 1px solid var(--ink); color: var(--ink); }
.btn-outline:hover { background: var(--ink); color: var(--paper); }

/* ---------- Text link with rule underline ---------- */
.link-rule {
  border-bottom: 1px solid var(--rule);
  /* Was a hardcoded 5px. Nearest scale step; imperceptible on an
     11px uppercase micro-label underline. */
  padding-bottom: var(--s6);
  align-self: flex-start;
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

/* ---------- Dark tile (link or button) ---------- */
.tile-dark {
  background: var(--ink-soft);
  color: var(--paper);
  padding: var(--s14) var(--s22);
  display: inline-flex;
  align-items: baseline;
  gap: var(--s16);
  align-self: flex-start;
  /* The om studiesang tile is now a <button> (click-to-play audio facade,
     theme/js/audio.js) — neutralise the UA button chrome so both element
     kinds render identically. All no-ops on an <a>. */
  border: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.tile-dark:hover { background: var(--ink); color: var(--paper); }
.tile-dark .tile-label {
  font-family: var(--serif);
  font-style: italic;
  font-size: 18px;
}
.tile-dark .tile-cta {
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--rule);
}

/* ---------- Lightbox trigger ----------
   Wraps a real photograph when partials/picture.html.twig is called with
   `lightbox_group` (see that file's docblock) — a plain reset so the
   <button> occupies exactly the box the bare <img> used to, with none of
   the browser's default button chrome (padding, border, background)
   disturbing the grid/hero layout it sits inside. */
.lightbox-trigger {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  border: 0;
  background: none;
  font: inherit;
  text-align: inherit;
  cursor: pointer;
}

/* ---------- Lightbox overlay ---------- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  /* --ink, not pure black — see DESIGN_GUIDELINES.md's colour system. */
  background: rgba(36, 23, 21, 0.96);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s34) var(--s70);
}
.lightbox[hidden] { display: none; }

/* theme/js/lightbox.js toggles this on <html> for exactly as long as the
   overlay is open — html, not just body, because on the taller routes
   (e.g. a project detail page) body's own height already exceeds the
   viewport and html is the element that actually scrolls. */
html.lightbox-open,
html.lightbox-open body {
  overflow: hidden;
}

.lightbox-figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s14);
  max-width: 100%;
  max-height: 100%;
  margin: 0;
}
.lightbox-image {
  display: block;
  max-width: 100%;
  max-height: 76vh;
  width: auto;
  height: auto;
  object-fit: contain;
  /* Same desaturation recipe every other photograph on the site carries —
     DESIGN_GUIDELINES.md §5 ("all images share the same filter") — with
     the same per-image .photo-grayscale override (theme/js/lightbox.js
     reads it off the trigger's data-lightbox-grayscale). */
  filter: var(--photo-filter);
}
.lightbox-image.photo-grayscale { filter: var(--photo-filter-grayscale-recipe); }

.lightbox-caption {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: var(--s14);
  /* .micro-11's own `color: var(--muted)` is tuned for paper backgrounds;
     the overlay backdrop is a fixed dark scrim, so this needs a light tone
     that stays light in every palette — see tokens.css's --on-scrim-*. */
  color: var(--on-scrim-muted);
}

.lightbox-close,
.lightbox-nav {
  position: absolute;
  width: 44px;
  height: 44px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--on-scrim-muted);
  color: var(--on-scrim);
  font-family: var(--sans);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}
.lightbox-close:hover,
.lightbox-nav:hover { background: var(--on-scrim-hover); }
.lightbox-close { top: var(--s26); right: var(--s26); }
.lightbox-prev { left: var(--s26); top: 50%; transform: translateY(-50%); }
.lightbox-next { right: var(--s26); top: 50%; transform: translateY(-50%); }
/* Hidden for a single-image group (nothing to step between) — also removes
   both from the tab order, which is what lets theme/js/lightbox.js's focus
   trap treat "visible" and "focusable" as the same set. */
.lightbox-nav[hidden] { display: none; }

/* --accent (the sitewide :focus-visible outline colour, base.css) is a
   muted brown tuned for the --paper background every other focus ring
   appears on — too low-contrast against this overlay's dark backdrop. */
.lightbox :focus-visible { outline-color: var(--on-scrim); }

/* ---------- Photography ---------- */
.photo { object-fit: cover; filter: var(--photo-filter); width: 100%; }
/* The client's per-image "vis i gråtone" override (partials/picture.html.twig's
   `grayscale` param). Opts a single photo INTO the desaturation recipe —
   applies var(--photo-filter-grayscale-recipe), which always forces
   grayscale(1) regardless of --photo-filter's current value, so this works
   whether the theme's global grayscale setting is on or off (the previous
   `filter: none` design could only ever remove desaturation, so it did
   nothing when the global default was already colour). Same specificity as
   .photo (one class each) — this rule must stay AFTER .photo in this file
   so the cascade picks it, and partials/video.html.twig's showreel-poster
   override instead uses the compound `.video-facade.photo-grayscale`
   selector in pages.css, since pages.css loads after this file and a
   same-specificity rule there would otherwise win back over this one. */
.photo-grayscale { filter: var(--photo-filter-grayscale-recipe); }
.photo-3-4 { aspect-ratio: 3 / 4; }
.photo-4-3 { aspect-ratio: 4 / 3; }
