/*
Theme Name: Rafael Riefler
Theme URI: https://rafaelriefler.com
Author: Rafael Riefler
Author URI: https://rafaelriefler.com
Description: Fully independent, purpose-built theme for the Rafael Riefler portfolio. Not a child theme. Design tokens sourced from handoff/01-design-tokens.md (approved Claude Design handoff).
Version: 0.1.0
Requires at least: 6.5
Requires PHP: 8.0
Tested up to: 7.0
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: rafael-riefler
*/

/* =========================================================================
   DESIGN TOKENS
   Source of truth: handoff/01-design-tokens.md. Values below are transcribed
   exactly; do not approximate. Component-specific layout values (grid column
   templates, per-card gap widths) are added when the components that use
   them are built, not here — this file holds only the tokens that are
   global and single-valued.
   ========================================================================= */
:root {
  /* Colour */
  --rr-bone: #EEECE6;
  --rr-bone-2: #D7D4CC;
  --rr-ink: #111111;
  --rr-dark: #171717;
  --rr-blue: #375BFF;
  --rr-error: #C63A1E;

  --rr-header-bg: rgba(238, 236, 230, 0.88);
  --rr-dock-bg: rgba(23, 23, 23, 0.94);

  --rr-rule: rgba(17, 17, 17, 0.12);
  --rr-rule-list: rgba(17, 17, 17, 0.2);
  --rr-rule-control-min: rgba(17, 17, 17, 0.28);
  --rr-rule-control-max: rgba(17, 17, 17, 0.4);

  --rr-text-secondary: rgba(17, 17, 17, 0.75);
  --rr-text-meta: rgba(17, 17, 17, 0.6);
  --rr-text-label: rgba(17, 17, 17, 0.5);
  --rr-text-inactive: rgba(17, 17, 17, 0.45);

  --rr-ondark-nav: rgba(238, 236, 230, 0.8);
  --rr-ondark-body: rgba(238, 236, 230, 0.7);
  --rr-ondark-meta: rgba(238, 236, 230, 0.55);
  --rr-ondark-legal: rgba(238, 236, 230, 0.45);

  --rr-selection-bg: var(--rr-blue);
  --rr-selection-fg: var(--rr-bone);

  /* Type families (self-hosted; see assets/css/fonts.css). system-ui/
     sans-serif remain as the fallback stack for the brief window before
     the woff2 files finish loading, or if they fail to load. */
  --rr-font-display: 'Space Grotesk', system-ui, sans-serif;
  --rr-font-body: 'Instrument Sans', system-ui, sans-serif;
  --rr-font-mono: 'Fragment Mono', ui-monospace, monospace;

  /* Type scale — role: size, from 01-design-tokens.md's Type table.
     Ranges given as a single value in the source (e.g. "clamp(...)")
     transcribe directly; ranges given as two context-dependent numbers
     (e.g. meta 11–12px) keep both bounds as separate tokens rather than
     inventing a midpoint. */
  --rr-size-hero-cinematic: clamp(48px, 9.4vw, 168px);
  --rr-size-hero-editorial: clamp(52px, 9vw, 158px);
  --rr-size-h1-page: clamp(48px, 8vw, 140px);
  --rr-size-h1-project: clamp(40px, 7vw, 118px);
  --rr-size-h2-section: clamp(30px, 3.6vw, 60px);
  --rr-size-h2-home: clamp(38px, 5vw, 84px);
  --rr-size-h2-block: clamp(24px, 2.2vw, 36px);
  --rr-size-h3-card: clamp(22px, 2.4vw, 40px);
  --rr-size-lead: clamp(17px, 1.4vw, 22px);
  --rr-size-body: clamp(16px, 1.25vw, 19px);
  --rr-size-body-secondary: 15px;
  --rr-size-summary: clamp(22px, 2.4vw, 38px);
  --rr-size-meta-min: 11px;
  --rr-size-meta-max: 12px;
  --rr-size-button: 13px;
  --rr-size-input: 16px; /* minimum — prevents iOS zoom, do not reduce */

  /* Measure caps (max-width in ch) */
  --rr-measure-body: 62ch;
  --rr-measure-secondary: 56ch;
  --rr-measure-footer: 30ch;
  /* leads measure 40–52ch and card-grid minmax 220–300px are context-
     dependent per component in the source spec, not single global values —
     applied directly where each component is built, not tokenised here. */

  /* Layout primitives */
  --rr-gutter: clamp(20px, 4vw, 56px);
  --rr-section-pad: clamp(56px, 7vw, 110px);
  --rr-section-pad-home: clamp(64px, 9vw, 140px);
  --rr-section-pad-band: clamp(48px, 6vw, 88px);
  --rr-section-pad-contact: clamp(72px, 10vw, 150px);
  --rr-gap-card: clamp(14px, 3vw, 40px);
  --rr-gap-col-a: clamp(24px, 4vw, 64px);
  --rr-gap-col-b: clamp(28px, 5vw, 88px);
  --rr-gap-gallery: 14px;

  --rr-header-height: 76px;
  --rr-header-offset-desktop: 108px;
  --rr-header-offset-mobile: 88px;
  --rr-dock-height: 76px;
  --rr-dock-bottom: calc(10px + env(safe-area-inset-bottom));
  --rr-mobile-body-padding-bottom: calc(76px + env(safe-area-inset-bottom) + 24px);
  --rr-chapter-bar-bottom: 96px;
  --rr-chapter-sheet-bottom: 146px;
  /* Left clearance reserved for body content on chapter-rail pages at
     ≥1181px, so the fixed, vertically-centred rail never lands on text as
     it tracks scroll. Must exceed the rail's own widest rendered right
     edge (left: 22px + 1px track + 16px gap + longest chapter-link label;
     measured 140.7px on Armèlle/Mallorca, 161px on Schwangau's "05
     Selected work") with headroom for future label edits. See CHAPTER
     NAVIGATION below. */
  --rr-rail-clear: 200px;

  /* Breakpoints (media queries can't read custom properties — recorded here
     for reference and must be kept in sync wherever used):
     767/768 dock<->tablet · 780 layout stacking · 900 companions/index preview
     1100 tablet menu<->desktop dropdowns · 1180 chapter rail<->chapter bar */

  /* Borders, radii, shadows */
  --rr-border-width: 1px;
  --rr-border-width-accent: 2px;
  --rr-radius: 0; /* radius is 0 on everything, everywhere, no exceptions */
  --rr-shadow-dropdown: 0 24px 48px rgba(17, 17, 17, 0.12);

  /* Motion */
  --rr-fast: 180ms;
  --rr-base: 320ms;
  --rr-long: 640ms;
  --rr-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --rr-ease-soft: cubic-bezier(0.33, 1, 0.68, 1);
  --rr-reveal-duration: 700ms;
  --rr-menu-duration: 260ms;
  --rr-split-duration: 650ms;
  --rr-wordmark-settle: 440ms;
  --rr-wordmark-wave-desktop: 780ms;
  --rr-wordmark-wave-mobile: 640ms;
  --rr-discovery-duration: 820ms;
  --rr-marquee-standard: 28s;
  --rr-marquee-calm: 52s;
  --rr-marquee-kinetic: 14s;

  /* z-index hierarchy */
  --rr-z-progress: 100;
  --rr-z-dock: 95;
  --rr-z-sheet: 92;
  --rr-z-scroll-progress-copy: 80;
  --rr-z-header: 60;
  --rr-z-chapter-sheet: 59;
  --rr-z-chapter-bar: 58;
  --rr-z-home-section-nav: 55;
  --rr-z-chapter-rail: 50;
  --rr-z-image-overlay: 2;
}

/* =========================================================================
   RESET
   ========================================================================= */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body, h1, h2, h3, h4, p, figure, blockquote, dl, dd { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img, picture, video, canvas, svg { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; padding: 0; }
a { color: inherit; text-decoration: none; }

/* =========================================================================
   BASE TYPOGRAPHY AND COLOUR
   ========================================================================= */
body {
  background: var(--rr-bone);
  color: var(--rr-ink);
  font-family: var(--rr-font-body);
  font-size: var(--rr-size-body);
  line-height: 1.6;
}

h1, h2, h3 {
  font-family: var(--rr-font-display);
  font-weight: 600;
}

.rr-meta,
.rr-eyebrow,
.rr-caption {
  font-family: var(--rr-font-mono);
  font-size: var(--rr-size-meta-max);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

::selection {
  background: var(--rr-selection-bg);
  color: var(--rr-selection-fg);
}

/* =========================================================================
   FOCUS
   Never removed. 4px offset only on chapter rail/bar links (applied on the
   component itself once built).
   ========================================================================= */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--rr-blue);
  outline-offset: 2px;
}

/* =========================================================================
   VISIBILITY / DISPLAY DISCIPLINE
   [hidden] must win over any inline display style that JS toggles alongside
   it (rr-project.js switches and the chapter sheet rely on this).
   ========================================================================= */
[hidden] { display: none !important; }

/* =========================================================================
   GLOBAL RESPONSIVE SAFETY NET (≤780px)
   Several project-layout templates still carry the prototype's raw inline
   `grid-template-columns: minmax(...)` two-column pairs (handoff/
   08-portability-audit.md item 3 — "convert repeated inline blocks into
   classes" is a later cleanup, not yet done everywhere). An inline style
   cannot be overridden by a class-based media-query rule, so — exactly like
   the prototype's own base <style> block (Home.dc.html line 52) — force
   every such pair to one column below the text-block-grid breakpoint via an
   attribute selector. This is a safety net, not a substitute for giving each
   template its own class once built out; it prevents silent horizontal
   overflow / uncollapsed column pairs on every route that still has them.
   ========================================================================= */
@media (max-width: 780px) {
  [style*="grid-template-columns: minmax"] {
    grid-template-columns: 1fr !important;
  }
}

/* =========================================================================
   LAYOUT PRIMITIVES
   ========================================================================= */
.rr-section {
  padding-block: var(--rr-section-pad);
  padding-inline: var(--rr-gutter);
}

.rr-container {
  width: 100%;
}

/* No max page width: layouts are full-bleed with gutters; content columns
   are capped by ch measures on the elements that hold copy, not here. */
.rr-measure-body { max-width: var(--rr-measure-body); }
.rr-measure-secondary { max-width: var(--rr-measure-secondary); }

/* =========================================================================
   IMAGE RATIO UTILITIES
   One wrapper class per declared ratio so no image causes layout shift.
   ========================================================================= */
.rr-ratio-21x9 { aspect-ratio: 21 / 9; }
.rr-ratio-16x10 { aspect-ratio: 16 / 10; }
.rr-ratio-16x9 { aspect-ratio: 16 / 9; }
.rr-ratio-4x3 { aspect-ratio: 4 / 3; }
.rr-ratio-4x5 { aspect-ratio: 4 / 5; }
.rr-ratio-3x4 { aspect-ratio: 3 / 4; }

/* =========================================================================
   FILTERED-IMAGE TREATMENT (exact, from 01-design-tokens.md)
   Prototype used a custom <image-slot> element; production applies the same
   treatment to a plain <figure class="rr-img"><img></figure> wrapper per
   handoff/08-portability-audit.md item 2.
   ========================================================================= */
.rr-img {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.rr-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(0.55) sepia(0.14) saturate(1.15) contrast(1.14) brightness(0.97);
  transition: filter var(--rr-reveal-duration) var(--rr-ease);
}

.rr-img::before,
.rr-img::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: var(--rr-z-image-overlay);
  pointer-events: none;
  transition: opacity var(--rr-reveal-duration) var(--rr-ease);
}

.rr-img::before {
  mix-blend-mode: soft-light;
  opacity: 0.95;
  background-image:
    linear-gradient(168deg, rgba(244, 241, 234, 0.42) 0%, rgba(244, 241, 234, 0.04) 44%, rgba(38, 33, 28, 0.28) 100%);
  /* fine-grain noise layer: add the ~160px fractal-noise SVG data: URL (or a
     small PNG per portability audit item 11) when the image layer is built */
}

.rr-img::after {
  mix-blend-mode: multiply;
  background-image:
    radial-gradient(112% 96% at 50% 38%, rgba(30, 26, 22, 0) 46%, rgba(30, 26, 22, 0.34) 100%),
    linear-gradient(180deg, rgba(238, 236, 230, 0) 62%, rgba(46, 40, 34, 0.16) 100%);
}

a:hover .rr-img img,
a:focus-visible .rr-img img {
  filter: grayscale(0.06) sepia(0.03) saturate(1.06) contrast(1.05) brightness(1.01);
}
a:hover .rr-img::before,
a:focus-visible .rr-img::before,
a:hover .rr-img::after,
a:focus-visible .rr-img::after {
  opacity: 0.3;
}

@media print {
  .rr-img::before,
  .rr-img::after {
    display: none;
  }
}

/* =========================================================================
   REDUCED MOTION
   Global rule, present on every page — per-interaction opt-outs are added
   alongside each interaction as it is built (handoff/06-interaction-register.md).
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* =========================================================================
   SKIP LINK
   ========================================================================= */
.rr-skip-link {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 200;
  background: var(--rr-ink);
  color: var(--rr-bone);
  padding: 12px 20px;
  font-family: var(--rr-font-mono);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  transition: top var(--rr-fast) var(--rr-ease);
}
.rr-skip-link:focus {
  top: 12px;
}

/* =========================================================================
   BUTTONS
   ========================================================================= */
.rr-btn {
  display: inline-block;
  background: var(--rr-ink);
  color: var(--rr-bone);
  padding: 16px 30px;
  font-family: var(--rr-font-body);
  font-size: var(--rr-size-button);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  border: 1px solid var(--rr-ink);
  transition: background var(--rr-fast) var(--rr-ease), color var(--rr-fast) var(--rr-ease), border-color var(--rr-fast) var(--rr-ease);
}
.rr-btn:hover,
.rr-btn:focus-visible {
  background: var(--rr-blue);
  border-color: var(--rr-blue);
  color: var(--rr-bone);
}
.rr-btn--outline {
  background: transparent;
  color: var(--rr-ink);
  border: 1px solid var(--rr-ink);
}
.rr-btn--outline:hover,
.rr-btn--outline:focus-visible {
  background: transparent;
  border-color: var(--rr-blue);
  color: var(--rr-blue);
}
.rr-btn--ondark {
  background: var(--rr-bone);
  color: var(--rr-ink);
  border-color: var(--rr-bone);
}
.rr-btn--ondark:hover,
.rr-btn--ondark:focus-visible {
  background: var(--rr-blue);
  border-color: var(--rr-blue);
  color: var(--rr-bone);
}
.rr-btn--small {
  padding: 12px 22px;
  font-size: 12px;
}
.rr-link-underline {
  font-size: var(--rr-size-button);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  border-bottom: 1px solid currentColor;
  padding-bottom: 4px;
  display: inline-block;
  width: max-content;
}
.rr-link-underline:hover,
.rr-link-underline:focus-visible {
  color: var(--rr-blue);
  border-bottom-color: var(--rr-blue);
}

/* =========================================================================
   HEADER / DESKTOP NAV / DROPDOWNS
   ========================================================================= */
.rr-header {
  position: sticky;
  top: 0;
  z-index: var(--rr-z-header);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 18px var(--rr-gutter);
  background: var(--rr-header-bg);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--rr-rule);
}
.rr-header__wordmark {
  font-family: var(--rr-font-display);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: 0.06em;
  white-space: nowrap;
}
.rr-nav {
  display: flex;
  align-items: center;
  gap: clamp(16px, 2.5vw, 36px);
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 500;
}
.rr-nav__item {
  /* Not `position: relative` — the panel's containing block is deliberately
     `.rr-header` (the nearest positioned ancestor once this isn't), so its
     `left/right: 0` spans the full header width edge-to-edge instead of the
     narrow trigger-centred rectangle this used to produce. */
  position: static;
}
.rr-nav__link {
  position: relative;
  display: inline-block;
}
.rr-nav__link::after {
  content: '';
  position: absolute;
  inset: -12px -8px;
}
.rr-nav__link.is-active {
  color: var(--rr-blue);
}
.rr-nav__panel {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  width: 100%;
  background: var(--rr-bone);
  box-shadow: var(--rr-shadow-dropdown);
  border-top: 1px solid var(--rr-rule);
  z-index: var(--rr-z-header);
}
.rr-nav__panel-inner {
  padding: 32px var(--rr-gutter) 40px;
  max-width: 1200px;
}
.rr-nav__panel-inner--single {
  max-width: none;
}
.rr-nav__panel-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(140px, 1fr));
  gap: 48px;
}
.rr-nav__panel-grid--single {
  grid-template-columns: minmax(180px, 260px);
}
.rr-nav__panel-link--featured {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* CSS :hover/:focus-within is the no-JS baseline (panel is a real descendant
   of the item, so it is always reachable by keyboard tab even with JS off).
   With JS active, interactions.js additionally toggles `.is-open` — see
   desktopDropdowns() — which drives the panel with a short close-delay timer
   so the panel survives the pointer's travel from trigger to panel instead
   of vanishing the instant :hover breaks across that gap. */
.rr-nav__item:hover > .rr-nav__panel,
.rr-nav__item:focus-within > .rr-nav__panel,
.rr-nav__item.is-open > .rr-nav__panel {
  display: block;
}
.rr-nav__panel-col {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.rr-nav__panel-heading {
  font-family: var(--rr-font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--rr-text-label);
  margin-bottom: 4px;
}
.rr-nav__panel-link {
  font-size: 13px;
  font-weight: 500;
  padding: 6px 0;
  border-left: 2px solid transparent;
  padding-left: 10px;
}
.rr-nav__panel-link.is-active {
  color: var(--rr-blue);
  font-weight: 700;
  border-left-color: var(--rr-blue);
}
.rr-nav__panel-link:hover,
.rr-nav__panel-link:focus-visible {
  color: var(--rr-blue);
}
.rr-nav__panel-meta {
  font-family: var(--rr-font-mono);
  font-size: 11px;
  color: var(--rr-text-meta);
}

@media (min-width: 1100px) {
  .rr-header__menu-trigger,
  .rr-dock {
    display: none !important;
  }
}
@media (max-width: 1099px) {
  .rr-nav {
    display: none !important;
  }
  .rr-nav__panel {
    display: none !important;
  }
}
@media (min-width: 768px) and (max-width: 1099px) {
  .rr-header__menu-trigger {
    display: inline-flex;
  }
}
@media (max-width: 767px) {
  .rr-header__menu-trigger {
    display: none !important;
  }
  .rr-header {
    flex-wrap: nowrap;
  }
  .rr-header .rr-btn {
    padding: 10px 14px;
    font-size: 11px;
  }
}

.rr-header__menu-trigger {
  /* No unscoped `display: none` here: the three media queries above already
     exhaustively cover every width (< 768 -> none, 768-1099 -> inline-flex,
     >= 1100 -> none !important). A same-specificity unscoped rule declared
     after them would win the cascade at every width regardless of media
     query, which is exactly what made the tablet trigger permanently
     display:none and unreachable by mouse or keyboard at 768-1099px. */
  font-family: var(--rr-font-mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  border: 1px solid var(--rr-rule-control-max);
  padding: 10px 18px;
}
.rr-header__menu-trigger:hover,
.rr-header__menu-trigger:focus-visible {
  border-color: var(--rr-blue);
  color: var(--rr-blue);
}

/* =========================================================================
   MOBILE / TABLET SHEET (checkbox-driven, works without JS)
   ========================================================================= */
.rr-menu-checkbox {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  width: 1px;
  height: 1px;
}
/* The checkbox itself is the only real keyboard focus target in this no-JS
   toggle pattern (its <label>s aren't natively focusable), but it is
   visually 1x1px, so the base `input:focus-visible` ring on it is
   invisible. Suppress that ring and draw it instead on whichever visible
   label currently represents the control, via sibling selectors. (The
   Services/Work sub-menu expand controls are real <button> elements — see
   .rr-sheet__expand below — and get their focus ring the ordinary way.) */
.rr-menu-checkbox:focus-visible {
  outline: none;
}
.rr-menu-checkbox:focus-visible:not(:checked) ~ .rr-header .rr-header__menu-trigger,
.rr-menu-checkbox:focus-visible:not(:checked) ~ .rr-dock .rr-dock__item--menu {
  outline: 2px solid var(--rr-blue);
  outline-offset: 3px;
}
.rr-menu-checkbox:checked:focus-visible ~ .rr-sheet .rr-sheet__close {
  outline: 2px solid var(--rr-blue);
  outline-offset: 3px;
}
.rr-sheet {
  display: none;
  position: fixed;
  inset: 0 0 calc(64px + env(safe-area-inset-bottom)) 0;
  z-index: var(--rr-z-sheet);
  background: var(--rr-dark);
  color: var(--rr-bone);
  overflow-y: auto;
  padding: 24px var(--rr-gutter) 48px;
}
@media (min-width: 768px) {
  .rr-sheet {
    inset: 0;
  }
}
.rr-menu-checkbox:checked ~ .rr-sheet {
  display: block;
}
.rr-sheet__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 32px;
}
.rr-sheet__close {
  font-family: var(--rr-font-mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  border: 1px solid rgba(238, 236, 230, 0.3);
  padding: 10px 16px;
}
.rr-sheet__close:hover,
.rr-sheet__close:focus-visible {
  border-color: var(--rr-blue);
  color: var(--rr-blue);
}
.rr-sheet__list {
  display: flex;
  flex-direction: column;
  flex: 1;
}
.rr-sheet__row {
  border-top: 1px solid rgba(238, 236, 230, 0.15);
}
.rr-sheet__row-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.rr-sheet__link {
  display: flex;
  align-items: baseline;
  gap: 16px;
  font-family: var(--rr-font-display);
  font-weight: 600;
  font-size: clamp(28px, 5.5vh, 44px);
  letter-spacing: -0.02em;
  text-transform: uppercase;
  padding: 14px 0;
  flex: 1;
}
.rr-sheet__num {
  font-family: var(--rr-font-mono);
  font-size: 12px;
  font-weight: 400;
  text-transform: none;
  color: rgba(238, 236, 230, 0.4);
}
.rr-sheet__link.is-active {
  color: var(--rr-blue);
}
/* Services/Work sheet-row expand controls are real <button type="button">
   elements (aria-expanded/aria-controls, toggled by interactions.js's
   sheetAccordion()) rather than the checkbox/label pattern used elsewhere in
   this sheet — a checkbox's associated <label> never receives focus itself
   and (on some Android/Chrome combinations) does not reliably forward
   Enter/Space activation, which is what made these controls unreliable. A
   real button is natively focusable and needs no such workaround. */
.rr-sheet__expand {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  background: none;
  border: 1px solid rgba(238, 236, 230, 0.25);
  color: var(--rr-bone);
  font-family: inherit;
  font-size: 20px;
  cursor: pointer;
}
.rr-sheet__expand:hover,
.rr-sheet__expand:focus-visible {
  border-color: var(--rr-blue);
  color: var(--rr-blue);
}
.rr-sheet__expand:focus-visible {
  outline: 2px solid var(--rr-blue);
  outline-offset: 2px;
}
/* Default to visible: without JS the expand <button> has no click handler
   (see interactions.js sheetAccordion()), so children stay reachable per
   this sheet's no-JS-still-reachable principle. JS marks each sublist
   collapsed on init (it's never visible mid-transition — the whole sheet is
   itself display:none until opened) and toggles `data-collapsed` on click. */
.rr-sheet__sublist {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 0 0 18px 44px;
}
.rr-sheet__sublist[data-collapsed] {
  display: none;
}
.rr-sheet__expand-icon {
  display: inline-block;
}
.rr-sheet__sublink {
  display: block;
  font-family: var(--rr-font-mono);
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 8px 0 8px 12px;
  color: rgba(238, 236, 230, 0.8);
  border-left: 2px solid transparent;
}
.rr-sheet__sublink.is-active {
  color: var(--rr-blue);
  border-left-color: var(--rr-blue);
  font-weight: 700;
}
.rr-sheet__cta {
  display: block;
  text-align: center;
  background: var(--rr-blue);
  color: var(--rr-bone);
  padding: 18px;
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  margin-top: 24px;
}
.rr-sheet__connect {
  margin-top: 28px;
  border-top: 1px solid rgba(238, 236, 230, 0.15);
  padding-top: 18px;
}
.rr-sheet__connect-heading {
  display: block;
  font-family: var(--rr-font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--rr-blue);
  margin-bottom: 6px;
}
.rr-sheet__social {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 14px 0;
  border-bottom: 1px solid rgba(238, 236, 230, 0.1);
}
.rr-sheet__social-label {
  display: block;
  color: var(--rr-bone);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.08em;
}
.rr-sheet__social:hover .rr-sheet__social-label,
.rr-sheet__social:focus-visible .rr-sheet__social-label {
  color: var(--rr-blue);
}
.rr-sheet__social-handle {
  display: block;
  font-family: var(--rr-font-mono);
  font-size: 11px;
  color: rgba(238, 236, 230, 0.5);
}
.rr-sheet__meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 10px;
  font-family: var(--rr-font-mono);
  font-size: 11px;
  color: rgba(238, 236, 230, 0.5);
  margin-top: 20px;
}
.rr-sheet__meta a {
  color: rgba(238, 236, 230, 0.5);
}

/* =========================================================================
   MOBILE BOTTOM DOCK
   ========================================================================= */
.rr-dock {
  display: none;
}
@media (max-width: 767px) {
  .rr-dock {
    display: flex;
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    bottom: var(--rr-dock-bottom);
    z-index: var(--rr-z-dock);
    background: var(--rr-dock-bg);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    box-shadow: 0 8px 32px rgba(17, 17, 17, 0.35);
    height: var(--rr-dock-height);
    align-items: center;
    gap: 0;
    padding: 5px;
    border-radius: 999px;
    max-width: calc(100vw - 16px);
    overflow-x: auto;
    scrollbar-width: none;
  }
  .rr-dock::-webkit-scrollbar {
    display: none;
  }
  /* overflow-x: auto above implicitly computes overflow-y to auto too (CSS
     Overflow spec), which clips the menu item's focus ring against the
     dock's own 5px padding; let it draw outside the pill while focus is
     inside, without affecting the resting appearance. */
  .rr-dock:focus-within {
    overflow: visible;
  }
  body.rr-has-dock {
    padding-bottom: var(--rr-mobile-body-padding-bottom);
  }
}
.rr-dock__item {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px 14px;
  border-radius: 999px;
  font-family: var(--rr-font-body);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(238, 236, 230, 0.78);
  white-space: nowrap;
}
.rr-dock__item.is-active {
  color: var(--rr-bone);
  background: var(--rr-blue);
}

/* =========================================================================
   FOOTER
   ========================================================================= */
.rr-footer {
  background: var(--rr-dark);
  color: var(--rr-bone);
  padding: var(--rr-section-pad-band) var(--rr-gutter) 32px;
}
@media (max-width: 780px) {
  .rr-footer {
    padding-bottom: 118px;
  }
}
.rr-footer__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: clamp(32px, 4vw, 56px);
  padding-bottom: clamp(40px, 5vw, 64px);
  border-bottom: 1px solid rgba(238, 236, 230, 0.15);
}
.rr-footer__col {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.rr-footer__wordmark {
  font-family: var(--rr-font-display);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 0.06em;
}
.rr-footer__blurb {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--rr-ondark-body);
  max-width: var(--rr-measure-footer);
}
.rr-footer__locator {
  margin: 0;
  font-family: var(--rr-font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--rr-ondark-meta);
}
.rr-footer__heading {
  font-family: var(--rr-font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--rr-blue);
}
.rr-footer nav {
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 500;
}
.rr-footer nav a,
.rr-footer__col > a {
  color: var(--rr-ondark-nav);
}
.rr-footer nav a:hover,
.rr-footer nav a:focus-visible,
.rr-footer__col > a:hover,
.rr-footer__col > a:focus-visible {
  color: var(--rr-blue);
}
.rr-footer__contact {
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-family: var(--rr-font-mono);
  font-size: 12px;
  color: var(--rr-ondark-meta);
}
.rr-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 16px;
  padding-top: 24px;
  font-family: var(--rr-font-mono);
  font-size: 11px;
  color: var(--rr-ondark-legal);
}
.rr-footer__bottom-links {
  display: flex;
  gap: 20px;
}
.rr-footer__bottom-links a:hover,
.rr-footer__bottom-links a:focus-visible {
  color: var(--rr-bone);
}

/* =========================================================================
   HERO
   ========================================================================= */
.rr-hero-cinematic {
  position: relative;
  min-height: calc(100svh - var(--rr-header-height));
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
  background: var(--rr-dark);
}
.rr-hero-cinematic__media {
  position: absolute;
  inset: -8% 0;
}
.rr-hero-cinematic__media .rr-img,
.rr-hero-cinematic__media .rr-img img {
  width: 100%;
  height: 100%;
}
.rr-hero-cinematic__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(17, 17, 17, 0.78) 0%, rgba(17, 17, 17, 0.15) 55%, rgba(17, 17, 17, 0.35) 100%);
}
.rr-hero-cinematic__content {
  position: relative;
  padding: 0 var(--rr-gutter) clamp(28px, 4vw, 52px);
  display: flex;
  flex-direction: column;
  gap: clamp(24px, 3vw, 40px);
}
.rr-hero-cinematic__content h1 {
  color: var(--rr-bone);
}
.rr-hero h1 {
  margin: 0;
  font-family: var(--rr-font-display);
  font-weight: 600;
  font-size: var(--rr-size-hero-cinematic);
  line-height: 0.92;
  letter-spacing: -0.03em;
  text-transform: uppercase;
}
.rr-hero h1 .rr-accent {
  color: var(--rr-blue);
}
.rr-hero__row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
}
.rr-hero__lede {
  margin: 0;
  font-size: clamp(18px, 1.6vw, 24px);
  line-height: 1.4;
  max-width: 40ch;
}
.rr-hero-cinematic .rr-hero__lede {
  color: var(--rr-bone);
}
.rr-hero__locator {
  margin: 0;
  font-family: var(--rr-font-mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--rr-text-meta);
}
.rr-hero-cinematic .rr-hero__locator {
  color: rgba(238, 236, 230, 0.7);
}
.rr-hero__actions {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
}

/* =========================================================================
   HOMEPAGE RIGHT-SIDE SECTION NAVIGATOR
   JS-generated (interactions.js homeSectionNav) from the [data-screen-label]
   sections already in front-page.php — handoff/06-interaction-register.md's
   home hero-section navigator. Hidden below the desktop nav breakpoint
   (matches the prototype's showSideNav: window.innerWidth > 1100).
   ========================================================================= */
.rr-section-nav {
  position: fixed;
  right: 22px;
  top: 50%;
  transform: translateY(-50%);
  z-index: var(--rr-z-home-section-nav);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
@media (max-width: 1100px) {
  .rr-section-nav {
    display: none;
  }
}
.rr-section-nav__item {
  font-family: var(--rr-font-mono);
  font-size: 10px;
  width: 34px;
  height: 26px;
  cursor: pointer;
  transition: all 0.25s;
  border: 1px solid var(--rr-rule-control-min);
  background: rgba(238, 236, 230, 0.85);
  color: var(--rr-text-meta);
}
.rr-section-nav__item.is-active {
  border-color: var(--rr-ink);
  background: var(--rr-ink);
  color: var(--rr-bone);
}
.rr-section-nav__item:hover,
.rr-section-nav__item:focus-visible {
  border-color: var(--rr-blue);
  color: var(--rr-blue);
}
.rr-section-nav__item.is-active:hover,
.rr-section-nav__item.is-active:focus-visible {
  color: var(--rr-bone);
}

/* =========================================================================
   PROJECT TICKER (marquee)
   ========================================================================= */
.rr-ticker {
  overflow: hidden;
  background: var(--rr-bone);
  border-bottom: 1px solid var(--rr-rule);
  padding: 13px 0;
}
.rr-ticker__track {
  display: flex;
  gap: 56px;
  width: max-content;
  animation: rrMarquee var(--rr-marquee-standard) linear infinite;
  font-family: var(--rr-font-mono);
  font-size: 13px;
  letter-spacing: 0.16em;
  color: var(--rr-text-meta);
  white-space: nowrap;
}
.rr-ticker__group {
  display: flex;
  gap: 56px;
}
.rr-ticker__sep {
  color: var(--rr-blue);
}
@keyframes rrMarquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

/* =========================================================================
   HOMEPAGE INTERLUDE (two split panels)
   ========================================================================= */
.rr-interlude a {
  transition: flex var(--rr-split-duration) var(--rr-ease);
}
.rr-interlude a:hover,
.rr-interlude a:focus-visible {
  flex: 1.7;
}
.rr-interlude__img,
.rr-interlude__img img {
  width: 100%;
  height: 100%;
}
@media (max-width: 780px) {
  .rr-interlude {
    flex-direction: column;
  }
  .rr-interlude a {
    min-height: 62vh;
  }
}

/* =========================================================================
   SECTION LABEL / EYEBROW
   ========================================================================= */
.rr-eyebrow-blue {
  font-family: var(--rr-font-mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--rr-blue);
}

/* =========================================================================
   PROJECT CARDS (Work image view + homepage)
   ========================================================================= */
.rr-cards {
  display: flex;
  flex-direction: column;
}
.rr-card {
  display: grid;
  grid-template-columns: minmax(50px, 1fr) minmax(220px, 6fr) minmax(150px, 3fr) 200px;
  gap: clamp(16px, 2vw, 32px);
  align-items: start;
  padding: clamp(22px, 2.6vw, 40px) 0;
  border-top: 1px solid var(--rr-rule-list);
}
.rr-card:hover,
.rr-card:focus-visible {
  color: var(--rr-blue);
}
.rr-card__link {
  display: contents;
  color: inherit;
}
.rr-card__index {
  font-family: var(--rr-font-mono);
  font-size: 12px;
  color: var(--rr-text-label);
}
.rr-card__body {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.rr-card__type {
  font-family: var(--rr-font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--rr-blue);
}
.rr-card__title {
  font-family: var(--rr-font-display);
  font-weight: 600;
  font-size: clamp(24px, 2.8vw, 46px);
  letter-spacing: -0.02em;
  line-height: 1.05;
}
.rr-card__desc {
  font-size: 15px;
  line-height: 1.55;
  color: var(--rr-text-secondary);
  max-width: 56ch;
}
.rr-card__cta {
  margin-top: 4px;
  color: var(--rr-blue);
  border-bottom-color: var(--rr-blue);
}
.rr-card__meta {
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-family: var(--rr-font-mono);
  font-size: 11px;
  color: var(--rr-text-meta);
}
.rr-card__meta-role {
  color: var(--rr-text-secondary);
  line-height: 1.5;
}
.rr-card__image {
  width: 200px;
  aspect-ratio: 4 / 3;
  justify-self: end;
}
@media (max-width: 780px) {
  .rr-card {
    grid-template-columns: 1fr;
  }
  .rr-card__image {
    width: 100%;
    justify-self: stretch;
  }
}

/* =========================================================================
   WORK INDEX VIEW
   ========================================================================= */
.rr-index-layout {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
  gap: clamp(24px, 4vw, 64px);
  align-items: start;
}
@media (max-width: 900px) {
  .rr-index-layout {
    grid-template-columns: 1fr;
  }
  .rr-index-preview {
    display: none;
  }
  .rr-index-thumb {
    display: block !important;
  }
}
.rr-index-rows {
  display: flex;
  flex-direction: column;
}
.rr-index-row {
  display: grid;
  grid-template-columns: minmax(40px, 1fr) minmax(180px, 7fr) minmax(120px, 4fr) minmax(90px, 2fr);
  gap: clamp(12px, 2vw, 28px);
  align-items: baseline;
  padding: clamp(18px, 2vw, 26px) 0;
  border-top: 1px solid var(--rr-rule-list);
}
.rr-index-row:hover,
.rr-index-row:focus-visible {
  color: var(--rr-blue);
}
@media (max-width: 780px) {
  .rr-index-row {
    grid-template-columns: 1fr;
  }
}
.rr-index-row__index {
  font-family: var(--rr-font-mono);
  font-size: 12px;
  color: var(--rr-text-label);
}
.rr-index-row__title {
  font-family: var(--rr-font-display);
  font-weight: 600;
  font-size: clamp(20px, 2.2vw, 34px);
  letter-spacing: -0.02em;
  line-height: 1.1;
}
.rr-index-row__meta {
  font-family: var(--rr-font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--rr-text-meta);
}
.rr-index-row__status {
  font-family: var(--rr-font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--rr-text-meta);
  justify-self: end;
  text-align: right;
}
@media (max-width: 780px) {
  .rr-index-row__status {
    justify-self: start;
    text-align: left;
  }
}
.rr-index-thumb {
  display: none;
  grid-column: 2 / -1;
  aspect-ratio: 16 / 10;
  margin-top: 12px;
}
.rr-index-preview {
  position: sticky;
  top: 120px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.rr-index-preview__caption {
  font-family: var(--rr-font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--rr-text-meta);
}

/* =========================================================================
   FILTERS + VIEW SWITCH
   ========================================================================= */
.rr-filters-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: clamp(32px, 4vw, 56px);
}
.rr-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  min-width: 0;
}
.rr-filter-btn {
  flex-shrink: 0;
  white-space: nowrap;
  font-family: var(--rr-font-mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  padding: 10px 18px;
  cursor: pointer;
  border: 1px solid var(--rr-rule-control-min);
  transition: background var(--rr-fast) var(--rr-ease), color var(--rr-fast) var(--rr-ease);
}
.rr-filter-btn.is-active {
  border-color: var(--rr-ink);
  background: var(--rr-ink);
  color: var(--rr-bone);
}
.rr-view-switch {
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--rr-font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--rr-text-label);
}
.rr-view-btn {
  font-family: var(--rr-font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  padding: 7px 12px;
  cursor: pointer;
  border: 1px solid var(--rr-rule-control-max);
}
.rr-view-btn.is-active {
  border-color: var(--rr-ink);
  background: var(--rr-ink);
  color: var(--rr-bone);
}
@media (max-width: 780px) {
  .rr-filter-btn,
  .rr-view-btn {
    min-height: 44px;
  }
}
.rr-no-results {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 18px;
  padding: clamp(40px, 6vw, 80px) 0;
}
.rr-no-results__label {
  font-family: var(--rr-font-mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--rr-text-label);
}
.rr-no-results__heading {
  margin: 0;
  font-family: var(--rr-font-display);
  font-weight: 600;
  font-size: clamp(22px, 2.4vw, 36px);
  letter-spacing: -0.01em;
  line-height: 1.15;
}

/* =========================================================================
   PROJECT META BLOCK
   ========================================================================= */
.rr-project-meta {
  display: grid;
  grid-template-columns: auto auto;
  gap: 10px 32px;
}
@media (max-width: 780px) {
  .rr-project-meta {
    grid-template-columns: 1fr;
  }
}
.rr-project-meta dt {
  font-family: var(--rr-font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--rr-text-label);
}
.rr-project-meta dd {
  margin: 0;
  font-size: 13px;
}

/* =========================================================================
   GALLERY / DOCUMENTATION GRID
   ========================================================================= */
.rr-gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--rr-gap-gallery);
}
.rr-gallery-cell {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.rr-gallery-cell figcaption {
  font-family: var(--rr-font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--rr-text-meta);
}

/* =========================================================================
   CHAPTER NAVIGATION
   Desktop (≥1181px): fixed rail, 1px track + blue scaleY progress fill,
   active link blue/600, fades out near the footer (assets/js/project.js
   toggles rail.style.opacity). ≤1180px: fixed dark bar (clear of the mobile
   dock) showing the live label + percentage; tapping it opens the sheet of
   chapter links. handoff/02-component-inventory.md component #20.
   ========================================================================= */
.rr-chapter-rail {
  display: none;
}
@media (min-width: 1181px) {
  .rr-chapter-rail {
    display: flex;
    align-items: center;
    gap: 16px;
    position: fixed;
    left: 22px;
    top: 50%;
    transform: translateY(-50%);
    z-index: var(--rr-z-chapter-rail);
    transition: opacity var(--rr-base, 320ms) linear;
  }
}
.rr-chapter-rail__track {
  position: relative;
  width: 1px;
  height: 140px;
  background: var(--rr-rule-control-min);
}
.rr-chapter-rail__progress {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: var(--rr-blue);
  transform: scaleY(0);
  transform-origin: top;
}
.rr-chapter-rail__links {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.rr-chapter-rail__links a {
  font-family: var(--rr-font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--rr-text-inactive);
}
.rr-chapter-rail__links a:hover,
.rr-chapter-rail__links a:focus-visible {
  color: var(--rr-blue);
}

/* Rail-safe content offset. [data-chapters]/.rr-chapter-rail only ever
   exists in the DOM on Armèlle, Mallorca and Schwangau (chapter-nav.php is
   only invoked by those three layout templates), so body:has() scopes this
   to exactly those pages without a body class or template edit — every
   other route's .rr-section/.rr-entry-content is untouched. Left-only: the
   right-hand gutter and every other page keep --rr-gutter unchanged. Below
   1181px the rail is display:none (replaced by the chapter bar/sheet), so
   this rule is wrapped in the same breakpoint and never affects that
   layout. */
@media (min-width: 1181px) {
  body:has(.rr-chapter-rail) .rr-section,
  body:has(.rr-chapter-rail) .rr-entry-content {
    padding-left: var(--rr-rail-clear);
  }
}

.rr-chapter-bar {
  display: none;
}
@media (max-width: 1180px) {
  .rr-chapter-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    bottom: var(--rr-chapter-bar-bottom);
    z-index: var(--rr-z-chapter-bar);
    width: min(calc(100vw - 32px), 520px);
    background: var(--rr-dark);
    color: var(--rr-bone);
    border: none;
    padding: 12px 18px;
    font-family: var(--rr-font-mono);
    font-size: 11px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
  }
  .rr-chapter-bar:hover,
  .rr-chapter-bar:focus-visible {
    color: var(--rr-blue);
  }
  .rr-chapter-bar__pct {
    color: var(--rr-blue);
    flex-shrink: 0;
  }
}
@media (max-width: 767px) {
  .rr-chapter-bar {
    bottom: calc(var(--rr-chapter-bar-bottom) + var(--rr-dock-height) + 10px);
  }
}

.rr-chapter-sheet {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: var(--rr-chapter-sheet-bottom);
  z-index: var(--rr-z-chapter-sheet);
  width: min(calc(100vw - 32px), 520px);
  background: var(--rr-dark);
  color: var(--rr-bone);
  display: flex;
  flex-direction: column;
  padding: 10px 18px;
  box-shadow: 0 24px 48px rgba(17, 17, 17, 0.35);
}
@media (max-width: 767px) {
  .rr-chapter-sheet {
    bottom: calc(var(--rr-chapter-bar-bottom) + var(--rr-dock-height) + 10px + 52px);
  }
}
.rr-chapter-sheet a {
  padding: 10px 0;
  border-top: 1px solid rgba(238, 236, 230, 0.15);
  font-family: var(--rr-font-mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(238, 236, 230, 0.8);
}
.rr-chapter-sheet a:first-child {
  border-top: none;
}
.rr-chapter-sheet a:hover,
.rr-chapter-sheet a:focus-visible {
  color: var(--rr-blue);
}

/* =========================================================================
   PROJECT PAGINATION
   ========================================================================= */
.rr-pagination {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--rr-rule-list);
}
@media (max-width: 780px) {
  .rr-pagination {
    grid-template-columns: 1fr;
  }
}
.rr-pagination__cell {
  padding: clamp(28px, 4vw, 48px) clamp(20px, 3vw, 32px);
  border-left: 1px solid var(--rr-rule-list);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.rr-pagination__cell:first-child {
  border-left: none;
}
@media (max-width: 780px) {
  .rr-pagination__cell {
    border-left: none;
    border-top: 1px solid var(--rr-rule-list);
  }
  .rr-pagination__cell:first-child {
    border-top: none;
  }
}
.rr-pagination__label {
  font-family: var(--rr-font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--rr-text-label);
}
.rr-pagination__title {
  font-family: var(--rr-font-display);
  font-weight: 600;
  font-size: clamp(18px, 1.8vw, 26px);
}
.rr-pagination__cell:hover .rr-pagination__title,
.rr-pagination__cell:focus-visible .rr-pagination__title {
  color: var(--rr-blue);
}

/* =========================================================================
   SWITCH GROUP (Coperni showroom index / Schwangau craft-channel)
   Component #19, interactions #13/#14. Buttons + one visible panel; JS
   (assets/js/project.js switches()) owns activation, aria-pressed and the
   320ms fade. Static (no JS): every panel is a plain stacked block, never
   hover-only or hidden — see the global [hidden]{display:none!important}
   rule and this block's own render.php, which never marks a panel hidden.
   ========================================================================= */
.rr-switch {
  margin-top: clamp(40px, 5vw, 72px);
  padding-top: clamp(24px, 3vw, 40px);
  border-top: 1px solid var(--rr-rule-list);
}
.rr-switch__buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: clamp(24px, 3vw, 40px);
}
.rr-switch__btn {
  font-family: var(--rr-font-mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  padding: 10px 18px;
  cursor: pointer;
  border: 1px solid var(--rr-rule-control-min);
  color: var(--rr-ink);
  background: transparent;
  transition: background var(--rr-fast, 180ms) var(--rr-ease), color var(--rr-fast, 180ms) var(--rr-ease), border-color var(--rr-fast, 180ms) var(--rr-ease);
}
.rr-switch__btn[aria-pressed="true"] {
  border-color: var(--rr-ink);
  background: var(--rr-ink);
  color: var(--rr-bone);
}
.rr-switch-panel {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.rr-switch-panel__label {
  font-family: var(--rr-font-mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  color: var(--rr-blue);
}

/* =========================================================================
   INFORMATION LAYERS (Mallorca)
   ========================================================================= */
.rr-layers {
  display: flex;
  flex-direction: column;
  gap: clamp(32px, 4vw, 56px);
}
.rr-layer {
  display: grid;
  grid-template-columns: 24px 1fr;
  gap: 20px;
  margin-top: clamp(32px, 4vw, 56px);
  padding-top: clamp(22px, 3vw, 40px);
  border-top: 1px solid var(--rr-rule-list);
}
.rr-layer:first-of-type {
  margin-top: 0;
}
.rr-layer__marker {
  width: 2px;
  background: var(--rr-rule-control-min);
}
.rr-layer.is-notable .rr-layer__marker {
  background: var(--rr-blue);
}
.rr-layer__label {
  font-family: var(--rr-font-mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  color: var(--rr-blue);
}

/* =========================================================================
   INDEX ENTRY ARTICLE (Research & Prototypes / Editorial index rows)
   ========================================================================= */
.rr-index-entry {
  display: grid;
  grid-template-columns: minmax(50px, 1fr) minmax(260px, 7fr) 240px;
  gap: clamp(16px, 2vw, 32px);
  align-items: start;
  padding: clamp(22px, 2.6vw, 40px) 0;
  border-top: 1px solid var(--rr-rule-list);
}
@media (max-width: 780px) {
  .rr-index-entry {
    grid-template-columns: 1fr;
  }
  .rr-index-entry__image {
    width: 100%;
    justify-self: stretch;
  }
}
.rr-index-entry__index {
  font-family: var(--rr-font-mono);
  font-size: 12px;
  color: var(--rr-text-label);
}
.rr-index-entry__body {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.rr-index-entry__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.rr-index-entry__chip {
  font-family: var(--rr-font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  border: 1px solid var(--rr-rule-control-min);
  padding: 5px 10px;
}
.rr-index-entry__date {
  font-family: var(--rr-font-mono);
  font-size: 11px;
  color: var(--rr-text-meta);
}
.rr-index-entry__title {
  margin: 0;
  font-family: var(--rr-font-display);
  font-weight: 600;
  font-size: clamp(22px, 2.4vw, 38px);
  letter-spacing: -0.02em;
  line-height: 1.08;
}
.rr-index-entry__note {
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--rr-text-secondary);
  max-width: 58ch;
}
.rr-index-entry__role {
  font-family: var(--rr-font-mono);
  font-size: 11px;
  color: var(--rr-text-meta);
}
.rr-index-entry__details summary {
  cursor: pointer;
  font-family: var(--rr-font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--rr-blue);
  padding: 8px 0;
}
.rr-index-entry__details p {
  margin: 6px 0 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--rr-text-secondary);
  max-width: 58ch;
}
.rr-index-entry__image {
  width: 240px;
  aspect-ratio: 4 / 3;
  justify-self: end;
}

/* =========================================================================
   TIMELINE (About)
   ========================================================================= */
.rr-timeline-row {
  display: grid;
  grid-template-columns: minmax(120px, 2fr) minmax(200px, 6fr) minmax(120px, 2fr);
  gap: clamp(16px, 2vw, 40px);
  padding: 22px 0;
  border-top: 1px solid var(--rr-rule-list);
  align-items: baseline;
}
@media (max-width: 780px) {
  .rr-timeline-row {
    grid-template-columns: 1fr;
  }
}
.rr-timeline-row__period {
  font-family: var(--rr-font-mono);
  font-size: 12px;
  color: var(--rr-text-meta);
}
.rr-timeline-row__title {
  font-family: var(--rr-font-display);
  font-weight: 600;
  font-size: clamp(18px, 1.7vw, 26px);
  letter-spacing: -0.01em;
}
.rr-timeline-row__detail {
  font-size: 14px;
  line-height: 1.5;
  color: var(--rr-text-secondary);
  max-width: 60ch;
}
.rr-timeline-row__place {
  font-family: var(--rr-font-mono);
  font-size: 11px;
  color: var(--rr-text-label);
  justify-self: end;
}
@media (max-width: 780px) {
  .rr-timeline-row__place {
    justify-self: start;
  }
}

/* =========================================================================
   SERVICES COMPANION
   Desktop: sticky frame, items stacked absolutely and crossfaded by
   assets/js/project.js's companions() (interaction #6). ≤900px: unsticks,
   items become their own inline grid cells — the CSS forces every item
   visible here, so this is also the correct no-JS/reduced-motion state.
   ========================================================================= */
.rr-companion {
  position: sticky;
  top: 120px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* No JS: every frame renders in normal flow, stacked and fully readable
   (interaction #6's "No JS: all frames visible") — only once .js confirms
   the crossfade script is present does the frame become one overlapping
   stack for companions() to animate between. */
.js .rr-companion__frame {
  position: relative;
  aspect-ratio: 4 / 5;
}
.js .rr-companion__item {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
}
.js .rr-companion__item:first-child {
  opacity: 1;
  pointer-events: auto;
}
.rr-companion__caption {
  font-family: var(--rr-font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--rr-text-meta);
}
@media (max-width: 900px) {
  .rr-companion {
    position: static;
  }
  .rr-companion__frame,
  .js .rr-companion__frame {
    position: static;
    aspect-ratio: auto;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 12px;
  }
  .rr-companion__item,
  .js .rr-companion__item {
    position: static;
    opacity: 1 !important;
    pointer-events: auto !important;
    aspect-ratio: 4 / 5;
  }
}

/* =========================================================================
   FORM (Contact)
   ========================================================================= */
.rr-form {
  display: flex;
  flex-direction: column;
  gap: 26px;
}
.rr-field {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* Honeypot: off-screen, untabbable, unlabelled-to-AT trap field. A human
   never sees or reaches it (aria-hidden + tabindex="-1" + visually hidden);
   a filled value on submit is treated server-side as a near-certain bot. */
.rr-field-trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
.rr-field__label {
  font-family: var(--rr-font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--rr-text-meta);
}
.rr-field input[type="text"],
.rr-field input[type="email"],
.rr-field select {
  border: none;
  border-bottom: 1px solid var(--rr-rule-control-max);
  background: transparent;
  padding: 10px 2px;
  font-size: var(--rr-size-input);
}
.rr-field textarea {
  border: 1px solid var(--rr-rule-control-max);
  background: transparent;
  padding: 12px;
  font-size: var(--rr-size-input);
  resize: vertical;
  line-height: 1.5;
}
.rr-field-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 26px;
}
.rr-field__error {
  font-size: 12px;
  color: var(--rr-error);
  min-height: 1.2em;
}
.rr-field.has-error input,
.rr-field.has-error textarea {
  border-color: var(--rr-error);
}
.rr-consent.has-error {
  outline: 1px solid var(--rr-error);
  outline-offset: 6px;
}
.rr-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.rr-chip {
  font-size: 13px;
  padding: 10px 16px;
  cursor: pointer;
  border: 1px solid var(--rr-rule-control-min);
  background: transparent;
}
.rr-chip:has(input:checked) {
  border-color: var(--rr-ink);
  background: var(--rr-ink);
  color: var(--rr-bone);
}
.rr-chip input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.rr-consent {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  cursor: pointer;
}
.rr-consent input {
  margin-top: 4px;
  width: 16px;
  height: 16px;
  accent-color: var(--rr-blue);
}
.rr-consent span {
  font-size: 13px;
  line-height: 1.5;
  color: var(--rr-text-secondary);
}
.rr-form-status {
  font-size: 13px;
  color: var(--rr-error);
  min-height: 1.4em;
}
.rr-form-status.is-visible {
  font-weight: 600;
}
.rr-form-success {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 18px;
}

/* =========================================================================
   LEGAL / PRIVACY / 404
   ========================================================================= */
.rr-legal {
  padding: clamp(48px, 7vw, 110px) var(--rr-gutter) clamp(80px, 10vw, 160px);
  max-width: 860px;
}
.rr-legal h2 {
  font-family: var(--rr-font-display);
  font-weight: 600;
  font-size: clamp(22px, 2.2vw, 30px);
  letter-spacing: -0.01em;
  margin: 0;
}
.rr-legal__block {
  display: flex;
  flex-direction: column;
  gap: 16px;
  border-top: 1px solid var(--rr-rule-list);
  padding-top: 36px;
}
.rr-legal__block:first-child {
  border-top: none;
  padding-top: 0;
}
.rr-legal__def-list {
  display: grid;
  grid-template-columns: minmax(140px, auto) 1fr;
  gap: 8px 28px;
  font-size: 15px;
}
.rr-legal__def-list dt {
  font-family: var(--rr-font-mono);
  font-size: 12px;
  color: var(--rr-text-label);
  align-self: baseline;
}
.rr-legal__def-list dd {
  margin: 0;
}
.rr-legal a {
  text-decoration: underline;
}

.rr-404 {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--rr-dark);
  color: var(--rr-bone);
}
.rr-404__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px var(--rr-gutter);
  border-bottom: 1px solid rgba(238, 236, 230, 0.15);
}
.rr-404__main {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  padding: clamp(40px, 6vw, 96px) var(--rr-gutter);
  gap: 28px;
}
.rr-404__heading {
  margin: 0;
  font-family: var(--rr-font-display);
  font-weight: 600;
  font-size: clamp(44px, 7.5vw, 130px);
  letter-spacing: -0.03em;
  line-height: 0.98;
  text-transform: uppercase;
  max-width: 12ch;
}
.rr-404__lede {
  margin: 0;
  max-width: 44ch;
  font-size: clamp(16px, 1.3vw, 20px);
  line-height: 1.6;
  color: rgba(238, 236, 230, 0.7);
}
.rr-404__footer {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 20px var(--rr-gutter);
  border-top: 1px solid rgba(238, 236, 230, 0.15);
  font-family: var(--rr-font-mono);
  font-size: 11px;
  color: rgba(238, 236, 230, 0.45);
}

/* =========================================================================
   ENTRY CONTENT (the_content() output on work detail pages: case-study body
   text alongside the purpose-built repeater blocks)
   ========================================================================= */
.rr-entry-content {
  padding: clamp(56px, 7vw, 110px) var(--rr-gutter);
  display: flex;
  flex-direction: column;
  gap: clamp(48px, 6vw, 88px);
  border-bottom: 1px solid var(--rr-rule);
}
.rr-entry-content > .rr-section,
.rr-entry-content > .rr-switch:first-child,
.rr-entry-content > .rr-layer:first-of-type {
  margin-top: 0;
}
.rr-entry-content h2 {
  font-size: var(--rr-size-h2-block);
  letter-spacing: -0.01em;
  margin: 0 0 20px;
}
.rr-entry-content p {
  max-width: 62ch;
  font-size: clamp(16px, 1.25vw, 19px);
  line-height: 1.65;
  margin: 0 0 16px;
}
.rr-entry-content ul {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 62ch;
  font-size: clamp(15px, 1.2vw, 18px);
  line-height: 1.6;
}
.rr-entry-content ul li::before {
  content: '— ';
}
.rr-entry-content > .rr-section,
.rr-entry-content > div[data-companion],
.rr-entry-content > section {
  border-bottom: none;
  padding: 0;
}

/* =========================================================================
   GENERIC SECTION HEADINGS reused across pages
   ========================================================================= */
.rr-h1-page {
  margin: 0;
  font-family: var(--rr-font-display);
  font-weight: 600;
  font-size: var(--rr-size-h1-page);
  letter-spacing: -0.03em;
  line-height: 0.96;
  text-transform: uppercase;
}
.rr-h2-section {
  margin: 0;
  font-family: var(--rr-font-display);
  font-weight: 600;
  font-size: var(--rr-size-h2-section);
  letter-spacing: -0.02em;
  line-height: 1.04;
  text-transform: uppercase;
}
