/* virtual republic – own stylesheet. Look values from the Fabrik theme "Airdura" (airdura-vars, theme.css) and the
   site's own Fabrik custom CSS, measured against the live site with tools/compare.mjs; no Fabrik code.
   Breakpoints: 41.6875rem (667 px, Fabrik's grid columns), 45rem (header band), 62rem (header band), 72.25rem (menu row,
   derived in the header part), 75rem, 75.5rem (menu spacing, derived there too), 105rem. */

/* ---------- fonts (self-hosted, licences in /fonts/) ---------- */
@font-face {
  font-family: "Dosis"; font-style: normal; font-display: swap; font-weight: 200 800;
  src: url(/fonts/dosis-latin-wght-normal.woff2) format("woff2-variations");
  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: "Dosis"; font-style: normal; font-display: swap; font-weight: 200 800;
  src: url(/fonts/dosis-latin-ext-wght-normal.woff2) format("woff2-variations");
  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: "Roboto"; font-style: normal; font-display: swap; font-weight: 300;
  src: url(/fonts/roboto-latin-300-normal.woff2) 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: "Roboto"; font-style: normal; font-display: swap; font-weight: 300;
  src: url(/fonts/roboto-latin-ext-300-normal.woff2) 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;
}

/* ---------- look values ---------- */
:root {
  /* colours */
  --bg: #000;
  --text: #bdb9b3;           /* copy, menu, page titles */
  --heading: #f5dc32;        /* image titles, overlay titles, active menu entry */
  --hover: #fff733;          /* links in text */
  --tags: #b9b9b9;           /* small print: video hint */
  --overlay: rgb(0 0 0 / .77);
  --icon: #8e8c89;           /* social icons */
  --footer-text: #fff;
  /* type */
  --font: "Dosis", sans-serif;
  --font-small: "Roboto", "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif;
  --copy: 400 20px/1.15 var(--font);            /* copy, card titles, footer title */
  --copy-spacing: 3px;
  --menu: 500 18px/.75 var(--font);
  --menu-spacing: 5px;
  --page-title: 500 27px/.96 var(--font);       /* project title */
  --page-title-spacing: 1px;
  --image-title: 900 29px/.89 var(--font);      /* slideshow captions, portfolio heroes (Dosis tops out at 800) */
  --subtitle: 400 15px/1.4 var(--font);         /* "View more" */
  --small: 300 12px/1.4 var(--font-small);      /* copyright, video hint */
  /* sizes */
  --logo-max: 400px;
  --logo-ratio: calc(275 / 1736);       /* logo file: height / width */
  --logo-star-inset: calc(10 / 1736);   /* its empty left margin, as a fraction of the width */
  --brand-w: calc(var(--logo-max) * .8);   /* the logo's width below 62rem (Fabrik); from 62rem the full --logo-max */
  --col-pad: 1.5rem;         /* the content column's side padding, as .capped sets it */
  /* The black header band: exactly --band-h high (plus the stacked menu when it is open below the band). Phones get a
     low band, from 45rem the Fabrik one: 2rem padding above and below the logo row. */
  --header-pad: .875rem;     /* above and below the logo row */
  --brand-gap: 0px;          /* 45rem to 62rem Fabrik keeps an empty title box under the logo */
  --header-row-h: calc(var(--brand-w) * var(--logo-ratio) + var(--brand-gap));   /* the logo row, from 62rem 4rem */
  --band-h: calc(2 * var(--header-pad) + var(--header-row-h));
  /* The flag fills the band in height. Band: 66 px up to 28.125rem (flag 92 px wide; the logo at most 240 px), 78.7 px
     up to 45rem (logo 320 px), 129.7 px up to 62rem, 128 px from 62rem (as Fabrik) */
  --flag-ratio: calc(254.182 / 182.091);   /* flag file: width / height */
  --flag-w: calc(var(--band-h) * var(--flag-ratio));
  /* space kept between the flag and the menu lettering or the menu button's box; on a phone the button's box (its lines
     sit 12 px inside it) is what comes closest, so .75rem there leaves the same 24 px of black as 1.5rem by lettering */
  --flag-gap: .75rem;
  /* The header's axes, as fractions of --band-h (the flag is --band-h high, so they are fractions of the flag's height,
     measured on the vector file vr-flag.svg):
     --arm-line: the straight line along the upper edges of the star's two side arms = star top 0.32504 + 0.382 * star
       height 0.23782 = 0.4159. The ascender top of the menu lettering sits on it.
     --word-axis: the wordmark's centre = star centre 0.444 + 3.4 / 128 (the extra 3.4 px the owner approved at the 128 px
       band, scaled with the band) = 0.4706. The wordmark is the same height at every width, so it sits on this axis at
       every width.
     --word-in-logo: the wordmark's centre in the logo file, as a fraction of the file's height: lettering spans rows
       98 to 232 of 275 = 0.6 (the file is not symmetric, the wordmark lies below the file's centre). */
  --arm-line: .4159;
  --word-axis: .4706;
  --word-in-logo: .6;
  --hero-cut: var(--band-h); /* the start page hero ends at the window's lower edge (Fabrik: 115 px from 45rem) */
  --inset: 2rem;             /* titles and icons on posters */
  --hero-crop: 2.35;         /* shape the portfolio hero posters are cropped to */
  --section-gap: 4rem;
}
@media (min-width: 45rem) {
  :root { --col-pad: 4%; --header-pad: 2rem; --brand-gap: 15px; --flag-gap: 1.5rem; --hero-cut: 115px; }
}
@media (min-width: 75rem) { :root { --col-pad: 6.875%; } }
@media (min-width: 105rem) { :root { --col-pad: 0px; } }
@media (max-width: 28.125rem) { :root { --logo-max: 300px; } }   /* logo 240 px wide on a phone */
@media (orientation: portrait) { :root { --hero-crop: .5625; } }
@media (min-width: 62rem) {
  :root { --brand-w: var(--logo-max); --brand-gap: 0px; --header-row-h: 4rem; --hero-cut: var(--band-h); }
}

/* ---------- page frame ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scrollbar-gutter: stable; }   /* a short page keeps the scrollbar's space: the logo does not jump between pages */
html, body { margin: 0; }
body {
  min-height: 100vh; display: flex; flex-direction: column;
  background: var(--bg); color: var(--text);
  font: 400 10px/1.15 var(--font); letter-spacing: var(--copy-spacing);
}
.site-main { flex: 1; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; height: auto; }
@media (hover: hover) { a:hover img { opacity: .95; } }
svg { fill: none; stroke: currentColor; stroke-width: 1.5; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.capped { margin: 0 auto; padding: 0 1.5rem; }
@media (min-width: 45rem) { .capped { padding: 0 4%; } }
@media (min-width: 75rem) { .capped { padding: 0 6.875%; } }
@media (min-width: 105rem) { .capped { padding: 0; max-width: 92.5rem; } }

/* ---------- header: logo left, menu right, the flag at the right edge; below the menu-row breakpoint the menu button
   sits left of the flag and the menu stacks under the band ---------- */
.site-header { position: relative; z-index: 10; background: var(--bg); }
/* The header row leaves the flag's width plus --flag-gap free at the right, so logo, menu and menu button never run
   under the flag (from 105rem part of that room lies outside the capped column) */
.header-row { display: flex; flex-wrap: wrap; align-items: center; }
.site-header > .header-row { padding-right: max(var(--col-pad), calc(var(--flag-w) + var(--flag-gap))); }
@media (min-width: 105rem) {
  .site-header > .header-row {
    padding-right: max(var(--col-pad), calc(var(--flag-w) + var(--flag-gap) - (100% - 92.5rem) / 2));
  }
}
/* The logo box is the band: --band-h high, the logo centred in it above the empty title box (--brand-gap). */
.brand {
  flex: 0 1 auto; min-width: 0; display: flex; align-items: center; height: var(--band-h);
  max-width: var(--brand-w); padding-bottom: var(--brand-gap);
}
/* The logo file has 10 of its 1736 px empty left of the star: shifted back, the star's tip sits on the content column's
   edge, where the left-aligned text of the text pages starts */
.brand img {
  display: block; min-width: 0; max-height: 6rem; width: auto;
  /* Sideways as above. Up or down: the logo is centred in the brand box's content area, which is --band-h less the empty
     title box --brand-gap high, so the wordmark's centre lies at (band - gap) / 2 + (--word-in-logo - .5) * logo height
     from the header's top. It is moved to --word-axis * band: the shift is --word-axis * band - (band - gap) / 2
     - (--word-in-logo - .5) * logo height, and a percentage in translate's second value is the logo's own height. */
  translate: calc(-100% * var(--logo-star-inset))
    calc(var(--word-axis) * var(--band-h) - (var(--band-h) - var(--brand-gap)) / 2 - (var(--word-in-logo) - .5) * 100%);
}
.menu-button {
  display: none; flex: none; margin: 0 0 0 auto; padding: 0; border: 0; background: none; color: var(--text);
  cursor: pointer;
}
.menu-button svg { display: block; width: 44px; height: 44px; }
.menu-button .icon-close, .open .menu-button .icon-open { display: none; }
.open .menu-button .icon-close { display: inline; }
.site-nav { flex-basis: 100%; }
.menu {
  margin: 0; padding: 2rem 0 0; list-style: none;
  font: var(--menu); letter-spacing: var(--menu-spacing); color: var(--text);
}
.menu a { display: block; padding: 1em 0; border-top: 1px solid var(--text); }
.menu a:hover, .menu .active a { color: var(--heading); }
/* With JavaScript (class "js" on <html>) the stacked menu folds behind the button. */
.js .menu-button { display: block; }
.js .site-header:not(.open) .site-nav { display: none; }
/* Beside the button the logo box grows from nothing up to --brand-w, so on a narrow phone the logo gets smaller and the
   button keeps its place in the band (a box at its full width would wrap the button to a line of its own) */
.js .brand { flex: 1 1 0; }
/* portfolio and tag pages: the header lies over the first hero; the open stacked menu pushes the hero down */
.page-portfolio .site-header { position: absolute; top: 0; left: 0; width: 100%; }
.page-portfolio .site-header.open { position: relative; }

/* The menu row: logo, menu and flag in one row, no menu button, from the width where they fit. A media query cannot
   read custom properties, so that width is written once, here, derived from them (desktop band 2rem + 4rem + 2rem =
   128 px, so the flag is 128 * 254.182 / 182.091 = 178.7 px wide):
   400 logo (--logo-max) + 488 menu (lettering of the five entries at 1em item spacing, measured) + 24 --flag-gap
   + 178.7 flag = 1090.7 px, over a 96% column (4% --col-pad at the left) = 1136.1 px, plus a 17 px classic scrollbar
   = 1153.1 px; 72.25rem (1156 px) rounds up to the next quarter rem. layout.test.mjs reads it from this rule. */
@media (min-width: 72.25rem) {   /* menu-row breakpoint */
  .js .brand { flex: 0 1 auto; }   /* no button: the logo at its full width, the menu takes the rest of the row */
  .js .menu-button { display: none; }
  .site-nav, .js .site-header:not(.open) .site-nav { display: block; flex: 1; flex-basis: auto; text-align: right; }
  .menu { padding: 0; white-space: nowrap; }
  .menu li { display: inline-block; }
  .menu li + li { margin-left: 1em; }   /* tighter than Fabrik's 1.23em so logo, menu and flag share a row early */
  .menu a { padding: 0; border: 0; }
  /* The ascender top of the lettering (h, t, b of Dosis 500, measured in Chrome: .389em above the line box's centre) sits
     on the arm line, --arm-line * band from the header's top. The row centres the menu in the band, so the line box's
     centre moves from band / 2 to --arm-line * band + .389em (em is the menu's size, 18 px: 3.8 px up at band 128). */
  .menu { translate: 0 calc(var(--arm-line) * var(--band-h) + .389em - var(--band-h) / 2); }
  .page-portfolio .site-header.open { position: absolute; }   /* the menu is in the band again, the header lies over */
}
/* Fabrik's 1.23em item spacing (menu 504.6 px) once it fits beside logo and flag in the 93.125% column of 75rem:
   (400 + 504.6 + 24 + 178.7) / .93125 = 1189 px, plus 17 px scrollbar = 1206 px; 75.5rem (1208 px) rounds up */
@media (min-width: 75.5rem) { .menu li + li { margin-left: 1.23em; } }

/* The VR flag: decorative, at the viewport's right edge (the header spans it, a classic scrollbar stays outside), and
   at every width exactly as high as the band: top and bottom on the band's edges. The header row leaves room for it
   (padding-right above). */
.flag {
  display: block; position: absolute; top: 0; right: 0; width: var(--flag-w); height: var(--band-h);
  pointer-events: none;
}
/* ---------- text pages (about, imprint, privacy, 404) ---------- */
.content-text { display: flow-root; margin-top: 2rem; font: var(--copy); }   /* own context: margins stay inside, as in Fabrik */
.content-text a:hover { color: var(--hover); }
.content-text p { margin: 1.15em 0; }
.content-text > :first-child { margin-top: 0; }
.content-text > :last-child { margin-bottom: 0; }
.content-text figure { margin: 0; text-align: center; }   /* text is left-aligned; images (about: "awards & achievements") stay centred */
.content-text img { width: auto; }
.content-text h1, .content-text h2 { color: var(--heading); font-weight: 500; letter-spacing: var(--page-title-spacing); }
.content-text h1 { margin: 0 0 1.5rem; font: var(--page-title); }
.content-text h2 { margin: 2rem 0 .75rem; font-size: 20px; line-height: 1.15; }

/* ---------- footer: everything centred, the icons in one row under the title ---------- */
.site-footer { text-align: center; }
.footer-upper { padding-top: 4rem; padding-bottom: 3.1875rem; }
.footer-title { margin: 0; font: var(--copy); }
.footer-title a:hover { color: var(--hover); }
.social {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 0; padding: 20px 0 0; list-style: none;
}
.social li { height: 34px; margin: 0; }
.social a { display: inline-block; height: 2rem; vertical-align: top; color: var(--icon); }
.social a:hover, .social a:focus-visible { color: var(--hover); }
.social-icon { display: block; width: 34px; height: 34px; stroke-width: 1; }
.social-icon path { stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.footer-lower { padding: 1.5rem 0; color: var(--footer-text); font: var(--small); letter-spacing: 0; }
.footer-lower p { margin: 0; }
.footer-lower .footer-links { margin-top: .5rem; color: var(--icon); }
.footer-links a:hover { color: var(--hover); }

/* ---------- list pages: cards ---------- */
.grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; margin: 0; padding: 0; list-style: none; }
@media (min-width: 41.6875rem) { .grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 41.6875rem) { .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.card { position: relative; display: block; overflow: hidden; }
.poster { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: #111; }
.poster picture, .poster img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* title on the poster at its lower left; with a mouse it fades in together with the dark overlay */
.card-title { position: absolute; inset: 0; display: flex; align-items: flex-end; padding: var(--inset); }
.card-title h3 { margin: 0; color: var(--heading); font: var(--copy); letter-spacing: var(--copy-spacing); }
@media (hover: hover) {
  .card-title { background: var(--overlay); opacity: 0; transition: opacity 350ms ease; }
  .card:hover .card-title, .card:focus-visible .card-title { opacity: 1; }
}

/* slideshow: two columns on a phone, then three; the title in big type below the poster */
.grid-magazine { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-magazine > li { padding-bottom: var(--section-gap); }
.card-caption {
  margin: 0; padding: 1rem 0 var(--section-gap); color: var(--heading);
  font: var(--image-title); letter-spacing: 0; text-transform: capitalize;
}
.card-caption a:hover { color: var(--hover); }
@media (min-width: 41.6875rem) { .grid-magazine { grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 4.16%; } }
@media (min-width: 45rem) { .grid-magazine > li { padding-bottom: 0; } }
@media (min-width: 75rem) { .grid-magazine { column-gap: 2.04%; } }

/* portfolio and tag pages: the header lies over the first hero; each hero a window high, title at its lower left */
.grid-hero { margin-bottom: 2rem; }
.grid-hero > li { position: relative; }
.grid-hero .card-hero .poster {
  position: relative; container-type: size;
  aspect-ratio: auto; height: calc(100vh - 6rem); height: calc(100svh - 6rem); min-height: 25em;
}
/* Fabrik crops the hero poster to 2.35:1 (9:16 in a portrait window) before filling the hero with it: the same
   framing comes from a box of that shape that covers the hero, centred, with the poster cropped into it */
.grid-hero .card-hero .poster img {
  position: absolute; left: 50%; top: 50%; translate: -50% -50%;
  width: max(100cqw, 100cqh * var(--hero-crop)); max-width: none; height: auto; aspect-ratio: var(--hero-crop);
}
.hero-titles { position: absolute; bottom: 0; left: 0; right: 0; padding-bottom: 6rem; }
.hero-title {
  width: 100%; margin: 0; color: var(--heading); font: var(--image-title); letter-spacing: 0; text-transform: capitalize;
}
.grid-hero .pager-down {
  position: absolute; left: 50%; bottom: var(--inset); margin: 0; transform: translateX(-50%); color: var(--heading);
}
@media (min-width: 45rem) {
  .grid-hero { margin-bottom: var(--section-gap); }
  .hero-title { width: 48%; }
}
@media (min-width: 75rem) {
  .grid-hero .card-hero .poster { max-height: 48rem; }
  .hero-title { width: 49%; }
}
/* link to the next list page: a light band like Fabrik's "View more"; a click loads the page in place (paging.js).
   The start page's "all missions" band (.all-missions) looks the same but is a plain link, paging.js leaves it alone. */
.pager, .all-missions {
  padding: 2rem 0 4rem; border-top: 1px solid var(--text); background: var(--text); color: var(--bg);
  text-align: center; font: var(--subtitle); letter-spacing: 0;
}
.pager a, .all-missions a { display: inline-block; }
.pager svg, .all-missions svg { display: block; width: 32px; height: 32px; margin: 0 auto; }
.pager span, .all-missions span { display: block; margin-top: 1rem; }

/* ---------- project pages: video, title, credits ---------- */
.embed-wrap, .media-list { margin-bottom: var(--section-gap); }
.media-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 41.6875rem) { .media-list { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.project-info { margin-bottom: calc(2 * var(--section-gap)); }
@media (min-width: 75rem) { .project-info { max-width: 50%; } }
.project-title h1 { margin: 0; font: var(--page-title); letter-spacing: var(--page-title-spacing); }
.project-content { margin-bottom: var(--section-gap); font: var(--copy); }
.project-content p { margin: 1.15em 0 0; }
.project-content a:hover { color: var(--hover); }
.pager-back-to { display: none; }   /* Fabrik's own CSS hides the back arrow; the link stays in the markup */

/* ---------- video: poster with play sign, player in place, unavailable notice, lightbox ---------- */
.video { position: relative; margin: 0; }
.video-link { display: block; position: relative; }
.video-link picture, .video-link img { display: block; width: 100%; }
.video .poster { background: #000; }
.icon-play { position: absolute; left: var(--inset); bottom: var(--inset); width: 48px; height: 32px; color: var(--heading); }
/* the hint sits in the gap below the video, so the page keeps Fabrik's rhythm */
.video-hint {
  position: absolute; top: 100%; left: 0; margin-top: .75rem;
  color: var(--tags); font: var(--small); letter-spacing: 0;
}
.video-hint a { text-decoration: underline; }
.video-hint a:hover { color: var(--hover); }
.video-frame { display: block; width: 100%; aspect-ratio: 16 / 9; border: 0; background: #000; }
.video-unavailable {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 1rem;
  background: var(--overlay); color: var(--heading); font: var(--copy); text-align: center; pointer-events: none;
}
.lightbox {
  width: 100%; max-width: none; height: 100%; max-height: none; margin: 0; padding: 0; border: 0;
  background: var(--overlay); color: var(--text); overflow: auto;
}
.lightbox::backdrop { background: var(--overlay); }
.lightbox-box { position: relative; width: min(100% - 2rem, 70rem); margin: 4rem auto 2rem; }
.lightbox-title { margin: 0 0 1rem; color: var(--heading); font: var(--copy); letter-spacing: var(--copy-spacing); }
.lightbox-player { position: relative; aspect-ratio: 16 / 9; background: #000; }
.lightbox-player .video-frame { height: 100%; }
/* in the lightbox the hint sits in the flow under the player (on a project page it hangs in the gap below the video) */
.lightbox-hint { position: static; margin: .75rem 0 0; }
.lightbox-credits { margin-top: 1rem; font-size: 18px; line-height: 1.4; }
.lightbox-credits a:hover { color: var(--hover); }
.lightbox-close {
  position: absolute; top: -3.25rem; right: 0; width: 2.5rem; height: 2.5rem; padding: .25rem; border: 0; background: none;
  color: var(--text); cursor: pointer;
}
.lightbox-close svg { width: 100%; height: 100%; stroke-width: 2; }
.lightbox-close:hover, .lightbox-close:focus-visible { color: var(--hover); }

/* ---------- start page hero: the looping reel from below the header to the window's lower edge ---------- */
.hero {
  position: relative; height: calc(100vh - var(--hero-cut)); height: calc(100svh - var(--hero-cut)); min-height: 25em;
  overflow: hidden; background: #111 center / cover no-repeat;
}
.hero video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
#mute, .pager-down { display: none; padding: 0; border: 0; background: none; color: #fff; cursor: pointer; }
#mute { padding: .5rem; }
#mute svg { display: block; width: 44px; height: 44px; }
.pager-down svg { display: block; width: 34px; height: 32px; }
#mute:hover, .pager-down:hover, #mute:focus-visible, .pager-down:focus-visible { color: var(--hover); }
.js #mute { display: block; position: absolute; right: 1rem; bottom: 1rem; }
/* the arrow sits 2rem above the hero's lower edge and keeps Fabrik's 6rem band below the hero */
.js .pager-down { display: block; }
.js .hero + .pager-down { position: relative; margin: -4rem auto 8rem; }
.top-padder { padding-top: 2rem; }
#mute[aria-pressed="true"] .on, #mute[aria-pressed="false"] .off { display: none; }
