/* =====================================================================
   MAIN.CSS  —  one stylesheet for the whole site
   Design tokens live in :root. Change the palette there once.

   A few conventions used throughout this file:

   - "shard" — an angular, faceted image crop, made with clip-path
     polygons rather than a rectangle. Used for photos, the home-page
     teaser images, and team portraits. Several classes share this idea
     (.shard-clip, .photo-shard, .year-photo, .team-img) with slightly
     different polygons — look for "clip-path: polygon(...)" to find
     every place this trick is used.

   - .mv-stage / .mv-frame — the frame around a <model-viewer>, cut into
     the same shard silhouette as the site's photos (see clip-path
     below). .mv-frame is used once (home page hero), .mv-stage
     everywhere else (results/field). Both expect a sibling .mv-glow div
     inside for the torch-light pulse effect. This is a purely visual
     frame — camera-controls, hotspots, and the AR button all still work
     exactly as before regardless of which frame class is used.

   - .reveal — a generic "fade up on load" animation, applied to most
     top-level content blocks so pages don't just snap into view.
   ===================================================================== */

:root {
  /* ---- colour palette: change any of these to re-theme the whole site ---- */
  --sand:        #E1D9BC;   /* primary body text colour */
  --sand-bright: #F0F0DB;   /* headings, buttons, brighter text */
  --steel:       #ACBAC4;   /* muted/secondary text (captions, hints, subtitles) */
  --ink:         #14110c;   /* near-black base colour (body background, text-on-light) */
  --ink-soft:    #211c14;   /* a slightly lighter near-black, used sparingly */
  --primary:     #b07d3c;   /* burnished bronze accent */
  --primary-dim: #8a5f2a;   /* darker bronze, for hover states on already-bronze elements */

  /* ---- translucent surfaces: glass-morphism panels, cards, tints ---- */
  --glass:       rgba(255,255,255,0.06);
  --glass-brd:   rgba(255,255,255,0.14);
  --card-bg:     rgba(20,17,12,0.45);
  --tint:        rgba(0,0,0,0.45);

  /* ---- typography: swap these to change fonts site-wide ---- */
  --font-display: 'Helvetica Neue', Arial, sans-serif;   /* headings */
  --font-body:    'Helvetica Neue', Arial, sans-serif;   /* body text, buttons */

  /* ---- fixed background photo (see .page-background below) ---- */
  --bg-image: url('../assets/fotos/DJI_0422.JPG');
}

/* Smooth cross-fade between full page navigations (landing -> home -> etc).
   Supported in Chromium browsers; other browsers just ignore this and keep
   the normal instant navigation, so it's a free upgrade with no fallback needed. */
@view-transition {
  navigation: auto;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  min-height: 100vh;
  font-family: var(--font-body);
  color: var(--sand);
  line-height: 1.7;
  background: var(--ink);
}

/* Fixed atmospheric background, layered by z-index so the home-page
   scroll-fade can sit between the photo and the faceted overlay:
     -3  .page-background   the aerial photo + vignette
     -2  .bg-fade           near-black layer (home only) faded in on scroll
     -1  .page-facets       translucent shard overlay (every page)
   Because the facets sit ABOVE the fade, they stay visible as it darkens. */
.page-background {
  position: fixed; inset: 0; z-index: -3;
  background: var(--bg-image) center/cover no-repeat;
}
.page-background::after {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(120% 90% at 50% 10%, transparent 40%, rgba(0,0,0,.55) 100%),
    linear-gradient(180deg, rgba(0,0,0,.25), rgba(0,0,0,.55));
}
/* Faceted low-poly shards (translucent tints in the site palette).
   Inline SVG stretched to cover the viewport. To re-cut the facets,
   edit the polygon points / fills in the data URI below. */
.page-facets {
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1600' height='900' preserveAspectRatio='none' viewBox='0 0 1600 900'%3E%3Cg stroke='%23F1EEE4' stroke-width='0.6' stroke-opacity='0.10'%3E%3Cpolygon points='0,0 420,0 250,210 0,260' fill='%23B07D3C' fill-opacity='0.20'/%3E%3Cpolygon points='420,0 880,0 640,240 250,210' fill='%2314110C' fill-opacity='0.26'/%3E%3Cpolygon points='880,0 1280,0 1230,180 640,240' fill='%23ACBAC4' fill-opacity='0.12'/%3E%3Cpolygon points='1280,0 1600,0 1600,320 1230,180' fill='%23B07D3C' fill-opacity='0.14'/%3E%3Cpolygon points='0,260 250,210 410,470 0,560' fill='%23ACBAC4' fill-opacity='0.09'/%3E%3Cpolygon points='250,210 640,240 760,500 410,470' fill='%2314110C' fill-opacity='0.20'/%3E%3Cpolygon points='640,240 1230,180 1160,540 760,500' fill='%23B07D3C' fill-opacity='0.11'/%3E%3Cpolygon points='1230,180 1600,320 1600,620 1160,540' fill='%2314110C' fill-opacity='0.28'/%3E%3Cpolygon points='0,560 410,470 540,720 0,820' fill='%23B07D3C' fill-opacity='0.16'/%3E%3Cpolygon points='410,470 760,500 900,760 540,720' fill='%23ACBAC4' fill-opacity='0.10'/%3E%3Cpolygon points='760,500 1160,540 1180,820 900,760' fill='%2314110C' fill-opacity='0.18'/%3E%3Cpolygon points='1160,540 1600,620 1600,900 1180,820' fill='%23B07D3C' fill-opacity='0.13'/%3E%3Cpolygon points='0,820 540,720 900,760 700,900 0,900' fill='%2314110C' fill-opacity='0.22'/%3E%3Cpolygon points='900,760 1180,820 1180,900 700,900' fill='%23ACBAC4' fill-opacity='0.10'/%3E%3C/g%3E%3C/svg%3E");
  background-size: cover; background-position: center;
}

h1, h2, h3 { font-family: var(--font-display); line-height: 1.2; }
h1 { font-size: clamp(2rem, 4.5vw, 2.5rem); font-weight: 600; letter-spacing: 2px; margin-bottom: 20px; }
h2 { font-size: clamp(1.5rem, 3vw, 2rem); font-weight: 500; }
h3 { font-size: 1rem; text-transform: uppercase; letter-spacing: .18em; color: var(--primary); font-weight: 600; }
p  { color: var(--sand-bright); font-size: 1.1rem; line-height: 1.6; }

a { color: inherit; }

/* ---------- top language / nav bar ---------- */
.topbar {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px clamp(16px, 4vw, 48px);
  background: linear-gradient(180deg, rgba(0,0,0,.6), transparent);
  backdrop-filter: blur(6px);
}
.brand { font-family: var(--font-display); font-weight: 900; letter-spacing: .04em; font-size: 1.05rem; color: var(--sand-bright); text-decoration: none; }
.brand span { color: var(--primary); }
.nav { display: flex; gap: clamp(8px, 2vw, 22px); flex-wrap: wrap; align-items: center; }
.nav a { text-decoration: none; font-size: .9rem; letter-spacing: .04em; opacity: .75; transition: opacity .25s, color .25s; padding: 4px 2px; }
.nav a:hover, .nav a.active { opacity: 1; color: var(--primary); }
.lang-switch { display: flex; gap: 6px; }
.lang-switch a {
  font-size: .72rem; letter-spacing: .08em; text-transform: uppercase;
  padding: 4px 9px; border: 1px solid var(--glass-brd); border-radius: 999px;
  text-decoration: none; opacity: .7; transition: all .2s;
}
.lang-switch a:hover { opacity: 1; }
.lang-switch a.active { background: var(--primary); border-color: var(--primary); color: var(--ink); opacity: 1; }

/* Bottom-of-page language switcher (see renderLangFooter in app.js).
   Sits in normal document flow after all page content — not fixed/
   floating — so it scrolls away with the rest of the page and appears
   once, at the very end, rather than hovering over content. */
.lang-footer {
  display: flex; justify-content: center;
  padding: 32px 16px 40px;
}
.lang-footer .lang-switch a { font-size: .78rem; padding: 6px 14px; }

/* ---------- generic content shell ---------- */
.wrap { max-width: 1100px; margin: 0 auto; padding: clamp(28px, 6vw, 72px) clamp(18px, 5vw, 40px); }

.glass {
  background: var(--card-bg);
  border: 1px solid var(--glass-brd);
  border-radius: 14px;
  backdrop-filter: blur(10px);
  padding: clamp(24px, 4vw, 48px);
}

.lede { font-size: 1.15rem; max-width: 62ch; }

/* fade-up on load */
.reveal { opacity: 0; transform: translateY(18px); animation: rise .8s cubic-bezier(.2,.7,.2,1) forwards; }
@keyframes rise { to { opacity: 1; transform: none; } }

/* ---------- buttons ---------- */
.button-group { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 20px; }
.btn {
  display: inline-block; padding: 13px 30px; font-family: var(--font-body);
  font-size: 1rem; letter-spacing: .03em; color: var(--sand-bright);
  text-decoration: none; border: 1.5px solid var(--sand-bright);
  border-radius: 6px; background: rgba(255,255,255,.07);
  transition: all .3s ease; backdrop-filter: blur(5px);
}
.btn:hover { background: var(--primary); border-color: var(--primary); color: var(--ink); transform: translateY(-3px); }
.btn-ghost { border-color: var(--glass-brd); }

.back-link { display: inline-block; margin-top: 26px; color: var(--steel); text-decoration: none; font-size: .9rem; opacity: .65; transition: opacity .3s; }
.back-link:hover { opacity: 1; }

/* ---------- home: stacked centered content boxes (original style) ---------- */
.home-stack { display: flex; flex-direction: column; align-items: center; gap: 0; }
.home-stack .subtitle { color: var(--steel); letter-spacing: .14em; text-transform: uppercase; font-size: .85rem; margin-bottom: 16px; }

.content-box {
  max-width: 1000px; width: 100%; text-align: center;
  background: rgba(255,255,255,0.05);
  padding: clamp(28px, 5vw, 50px);
  border-radius: 10px;
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255,255,255,0.1);
}
.inner-content-box { max-width: 1000px; width: 100%; text-align: center; padding: clamp(28px, 5vw, 50px) clamp(20px, 4vw, 50px); }
.inner-content-box h2 { margin-bottom: 18px; }

/* ---------- home group dividers ---------- */
.group-divider {
  width: 100%; max-width: 1000px;
  display: flex; align-items: center; gap: 20px;
  margin: 34px 0 6px;
}
.group-divider::before, .group-divider::after {
  content: ""; flex: 1; height: 1px;
  background: linear-gradient(to right, transparent, rgba(255,255,255,.35), transparent);
}
.group-divider span {
  color: var(--steel); text-transform: uppercase;
  letter-spacing: .18em; font-size: .78rem; white-space: nowrap;
}

/* ---------- scroll-to-black background fade (home only) ----------
   A fixed near-black layer above the photo but below the faint facets,
   so as it fades in the photo darkens but the shards still ghost through.
   Opacity is driven by JS (initHomeScroll); starts fully transparent. */
.bg-fade {
  position: fixed; inset: 0; z-index: -2;
  background: #08070a;
  opacity: 0;
  pointer-events: none;
  will-change: opacity;
}

/* ---------- home alternating sections + shard images ---------- */
.home-section {
  width: 100%; max-width: 1100px;
  display: grid; grid-template-columns: 1fr 1fr;
  align-items: center; gap: clamp(20px, 4vw, 56px);
  margin: 10px 0;
}
.home-section.side-right .shard { order: 2; }
.home-section.side-right .section-text { order: 1; }
.home-section .section-text { margin: 0; }

.shard {
  opacity: 0;                         /* JS fades these in on scroll */
  will-change: opacity, transform;
  transition: opacity .15s linear;
}
/* shards used outside the home scroll effect (e.g. the 3D directory)
   are shown straight away */
.shard.is-static { opacity: 1; transform: none; }
.shard-clip {
  width: 100%; aspect-ratio: 4 / 3;
  /* an angular shard silhouette, echoing the faceted background */
  clip-path: polygon(8% 0, 100% 6%, 92% 100%, 0 88%);
  overflow: hidden;
  box-shadow: 0 18px 50px rgba(0,0,0,.5);
}
.shard-left  .shard-clip { clip-path: polygon(6% 4%, 100% 0, 94% 92%, 0 100%); }
.shard-right .shard-clip { clip-path: polygon(0 0, 94% 6%, 100% 100%, 8% 90%); }
.shard-clip img, .shard-clip video { width: 100%; height: 100%; object-fit: cover; display: block; }

@media (max-width: 760px) {
  .home-section { grid-template-columns: 1fr; }
  .home-section.side-right .shard,
  .home-section.side-right .section-text { order: 0; }
  .shard-clip { aspect-ratio: 16 / 9; }
}

/* extra scroll room at the foot of the home page so the final section's
   shard can travel to the viewport centre (where it's fully visible) */

/* respect reduced-motion: no parallax drift, simple visibility */
@media (prefers-reduced-motion: reduce) {
  .shard { transition: none; transform: none !important; }
}


/* ---------- trenches: text/photo pair rows (blocks system) ----------
   Two-column row used by the "textphoto"/"phototext" block types in a
   trench's `blocks` array. .flip swaps which side the photo sits on —
   order is controlled explicitly here (not inherited from DOM position)
   so the flip is always reliable regardless of markup order. */
.trench-pair {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(20px, 4vw, 40px); align-items: center;
  margin: 28px 0;
}
.trench-pair .tp-text  { order: 1; }
.trench-pair .tp-photo { order: 2; }
.trench-pair.flip .tp-text  { order: 2; }
.trench-pair.flip .tp-photo { order: 1; }
.trench-pair .tp-photo img {
  width: 100%; height: clamp(220px, 32vw, 360px); object-fit: cover;
  display: block; box-shadow: 0 10px 36px rgba(0,0,0,.45);
  clip-path: polygon(8% 0, 100% 6%, 92% 100%, 0 88%);
}
.trench-pair.flip .tp-photo img { clip-path: polygon(0 0, 94% 6%, 100% 100%, 8% 90%); }
@media (max-width: 720px) {
  .trench-pair, .trench-pair.flip { grid-template-columns: 1fr; }
  .trench-pair .tp-text, .trench-pair .tp-photo,
  .trench-pair.flip .tp-text, .trench-pair.flip .tp-photo { order: 0; }
}

/* ---------- trenches selector ----------
   The T1/T2/T3 tab buttons above the detail panel; .active marks the
   currently-selected tab (toggled by JS in renderTrenches). */
.trench-tabs { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-top: 26px; }
.trench-tab {
  padding: 10px 24px; font-family: var(--font-body); font-size: 1rem;
  color: var(--sand-bright); cursor: pointer;
  border: 1.5px solid var(--sand-bright); border-radius: 6px;
  background: rgba(255,255,255,.07); backdrop-filter: blur(5px);
  transition: all .3s ease;
}
.trench-tab:hover { transform: translateY(-3px); }
.trench-tab.active { background: var(--primary); border-color: var(--primary); color: var(--ink); }
#trench-detail { text-align: center; transition: opacity .3s ease; }

/* ---------- model viewer ----------
   Every <model-viewer> gets the same base treatment (size, dark
   background, the desaturated/contrasty "moody" filter) regardless of
   which page it's on. The frame around it (.mv-stage or .mv-frame,
   further down) cuts it into the site's shard silhouette; .mv-glow and
   .mv-stencil (further down) are optional layered siblings for the
   torch-pulse and grain-overlay effects.

   Stacking order inside a frame, back to front (z-index):
     0  .mv-glow      soft pulsing bronze glow behind the model
     1  model-viewer   the model itself
     5  .mv-stencil    grain/scratch overlay (only used on some viewers) */
model-viewer {
  width: 100%; height: clamp(320px, 55vh, 520px);
  background: rgba(0,0,0,.12); border-radius: 8px;
  margin: 18px 0 26px; --poster-color: transparent;
  /* moody grade: crushed a touch darker, desaturated, more contrasty —
     reads like torchlight rather than a studio product shot */
  filter: brightness(.86) contrast(1.16) saturate(.78);
}
.content-box model-viewer { height: 500px; }  /* fixed height override, used only by the home hero (inside .mv-frame > .content-box) */

/* Shared "torch glow" pulse behind the model — a slow, subtle breathing
   light rather than flat ambient fill. A dedicated element (not a
   pseudo-element) so it never collides with the corner-tick decorations. */
@keyframes torch-glow {
  0%, 100% { opacity: .55; }
  50%      { opacity: .85; }
}
.mv-glow {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(60% 55% at 50% 42%, rgba(176,125,60,.16), transparent 70%);
  animation: torch-glow 7s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .mv-glow { animation: none; opacity: .65; }
}

/* Worn-stencil overlay: fine procedural grain (SVG feTurbulence, no image
   asset needed) plus a few faint diagonal scratches, like it's being viewed
   through aged film or scratched parchment. Sits above the model but never
   intercepts pointer events, so orbiting and hotspots still work underneath. */
.mv-stencil {
  position: absolute; inset: 0; z-index: 5; pointer-events: none;
  background-image:
    repeating-linear-gradient(115deg, transparent 0 42px, rgba(240,240,219,.06) 42px 43px, transparent 43px 150px),
    repeating-linear-gradient(71deg, transparent 0 88px, rgba(20,17,12,.10) 88px 89px, transparent 89px 230px),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: cover, cover, 260px 260px;
  mix-blend-mode: overlay;
  opacity: .38;
}

/* ---------- interactive 3D viewer (results / field pages) ----------
   Same shard silhouette as the trench scans and photo gallery (see
   .trench-shard / .photo-shard), rather than a rounded/vignetted box —
   this is a purely visual choice: camera-controls, hotspots, the AR
   button, and everything else about the viewer's behaviour is
   untouched, it's just wearing the shard "frame" now instead of a box. */
.mv-stage {
  position: relative; width: 100%; aspect-ratio: 4 / 3;
  margin: 8px 0 22px;
  background: radial-gradient(120% 100% at 50% 20%, rgba(20,17,12,.4), rgba(0,0,0,.82));
  clip-path: polygon(8% 0, 100% 6%, 92% 100%, 0 88%);
  box-shadow: 0 18px 50px rgba(0,0,0,.55);
}
.mv-stage model-viewer {
  position: relative; z-index: 1;
  width: 100%; height: 100%; margin: 0; border-radius: 0;
  background: transparent; --poster-color: transparent;
}

/* ---------- home hero viewer frame ----------
   Same shard treatment as .mv-stage above — see that comment for why.
   width/max-width are REQUIRED here (unlike .mv-stage, which sits in a
   plain block-layout .wrap): .mv-frame is now a direct child of
   .home-stack, which is `display:flex; align-items:center`. A flex
   child with no explicit width shrinks to fit its content instead of
   filling the row — since model-viewer itself also has no intrinsic
   size to bootstrap from, that collapsed the whole box down to ~0px
   wide (looked like the model had vanished, not just gotten smaller).
   Matching .content-box's own width/max-width keeps the hero the same
   visual width as the text block above it. */
.mv-frame {
  position: relative;
  width: 100%; max-width: 1000px;
  margin: 18px 0 26px;
  background: radial-gradient(120% 100% at 50% 20%, rgba(20,17,12,.4), rgba(0,0,0,.82));
  clip-path: polygon(8% 0, 100% 6%, 92% 100%, 0 88%);
  box-shadow: 0 18px 50px rgba(0,0,0,.55);
}
.mv-frame model-viewer { position: relative; z-index: 1; margin: 0; background: transparent; }

/* hotspot markers — simple, legible circles: black rim, translucent
   white fill. Reads clearly against a constantly-rotating 3D scene.
   Positioning: model-viewer itself calculates screen position from
   each button's data-position/data-normal attributes and applies its
   own transform — don't add a competing `transform` here, since an
   inline style (which is what model-viewer sets) always wins over a
   stylesheet rule for the same property, silently breaking placement. */
.Hotspot {
  --s: 20px; width: var(--s); height: var(--s); border-radius: 50%;
  background: rgba(255,255,255,.55); border: 2px solid rgba(0,0,0,.85);
  box-shadow: 0 2px 8px rgba(0,0,0,.5);
  cursor: pointer; position: relative; padding: 0; transition: transform .2s ease, background .2s ease;
}
.Hotspot:not([data-visible]) { opacity: 0; pointer-events: none; }
.Hotspot:hover { transform: scale(1.18); background: rgba(255,255,255,.75); }
.HotspotAnnotation {
  position: absolute; left: 50%; bottom: calc(100% + 10px); transform: translateX(-50%);
  background: var(--ink); color: var(--sand-bright);
  padding: 8px 13px; border-radius: 5px; width: max-content; max-width: 230px;
  font-family: var(--font-body); font-size: .85rem; line-height: 1.4;
  border: 1px solid var(--glass-brd);
  opacity: 0; pointer-events: none; transition: opacity .2s ease;
  box-shadow: 0 8px 24px rgba(0,0,0,.45);
}
.HotspotAnnotation::after {
  content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  border: 6px solid transparent; border-top-color: var(--ink);
}
.Hotspot:hover .HotspotAnnotation, .Hotspot:focus .HotspotAnnotation { opacity: 1; }

/* guided-tour "active" marker: brighter fill, annotation forced open
   (not hover-only) so it's clear what's currently being focused on
   without needing to interact with it. Used by the home hero tour. */
.Hotspot.active { background: var(--primary); border-color: var(--sand-bright); }
.Hotspot.active .HotspotAnnotation { opacity: 1; }

/* navigation pins: a pin that links to another page reads as clickable —
   a bronze fill that gently pulses, and a "›" cue in its label. */
.Hotspot.is-link {
  background: rgba(176,125,60,.75); border-color: rgba(0,0,0,.85);
  animation: pinPulse 2.2s ease-in-out infinite;
}
.Hotspot.is-link:hover { transform: scale(1.25); animation: none; background: rgba(176,125,60,.9); }
.hs-go { margin-left: 6px; color: var(--primary); font-weight: 700; }
@keyframes pinPulse {
  0%, 100% { box-shadow: 0 2px 8px rgba(0,0,0,.5), 0 0 0 0 rgba(176,125,60,.5); }
  50%      { box-shadow: 0 2px 8px rgba(0,0,0,.5), 0 0 0 7px rgba(176,125,60,0); }
}
@media (prefers-reduced-motion: reduce) { .Hotspot.is-link { animation: none; } }

/* AR button (inside the stage) */
#ar-button {
  position: absolute; bottom: 16px; left: 50%; transform: translateX(-50%);
  font-family: var(--font-body); font-size: .72rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .12em;
  padding: 10px 18px; border: 1px solid var(--sand-bright);
  background: rgba(20,17,12,.6); color: var(--sand-bright);
  cursor: pointer; z-index: 5; border-radius: 6px; backdrop-filter: blur(5px);
  transition: all .2s ease;
}
#ar-button:hover { background: var(--primary); border-color: var(--primary); color: var(--ink); }

/* load progress bar */
.progress-bar {
  position: absolute; bottom: 0; left: 0; width: 100%; height: 4px;
  background: rgba(255,255,255,.12); z-index: 4;
}
.progress-bar.hide { display: none; }
.update-bar { height: 100%; width: 0%; background: var(--primary); transition: width .25s ease; }

/* control buttons under the stage */
.mv-controls { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; margin-top: 6px; }
.ctl {
  font-family: var(--font-body); font-size: .72rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .12em;
  padding: 10px 18px; border: 1px solid var(--sand-bright);
  background: transparent; color: var(--sand-bright); cursor: pointer;
  border-radius: 6px; transition: all .2s ease;
}
.ctl:hover { background: var(--sand-bright); color: var(--ink); }
.ctl.active { background: var(--primary); border-color: var(--primary); color: var(--ink); }
/* the AR shortcut in the control row: bronze, hidden until AR is confirmed */
.ctl-ar { display: none; text-decoration: none; background: var(--primary); border-color: var(--primary); color: var(--ink); }
.ctl-ar:hover { background: var(--primary-dim); border-color: var(--primary-dim); color: var(--sand-bright); }
.hint { margin-top: 16px; font-size: .85rem; color: var(--steel); font-style: italic; text-align: center; }

/* ---------- excavation timeline ---------- */
/* Un-boxed now (no .glass wrapper) — content just flows in the open
   page, same as the trenches page, instead of scrolling inside a
   fixed-height panel. */
.exc-display { transition: opacity .3s ease; margin-top: 30px; }
.exc-display h2 { margin-bottom: 18px; }
.exc-display p  { margin-bottom: 18px; }
/* Large, quiet "you are here in time" cue — sits just above each
   season's heading. Deliberately faint (var(--primary) at low opacity)
   so it reads as texture/atmosphere, not a competing headline. */
.exc-year-cue {
  font-family: var(--font-display); font-weight: 900;
  font-size: clamp(4rem, 12vw, 8rem); line-height: .8;
  color: var(--primary); opacity: .16;
  margin-bottom: -.12em;   /* pulls the real heading up close beneath it */
  user-select: none;
}
/* ---------- reusable angular photo "shard" (all non-background images) ----------
   Echoes the faceted background + the home-page section shards. Used on the
   excavation, history, landscape, trenches and team pages. Alternating cut
   directions stop repeated images looking identical. */
.photo-shard {
  width: 100%; margin: 10px 0 22px; display: block;
  overflow: hidden;
  clip-path: polygon(8% 0, 100% 6%, 92% 100%, 0 88%);
  box-shadow: 0 14px 40px rgba(0,0,0,.45);
}
.photo-shard img { width: 100%; max-height: 460px; object-fit: cover; display: block; }
/* alternate the silhouette: every other shard leans the other way */
.photo-shard:nth-of-type(even) { clip-path: polygon(0 0, 94% 6%, 100% 100%, 8% 90%); }
.photo-shard.cut-left  { clip-path: polygon(6% 4%, 100% 0, 94% 92%, 0 100%); }
.photo-shard.cut-right { clip-path: polygon(0 0, 94% 6%, 100% 100%, 8% 90%); }

/* Trenches page: the look-only spinning scan, cut into the same shard
   silhouette used everywhere else on the site now (photos, .mv-stage,
   .mv-frame), so it visually reads as "one more photo" in the gallery
   rather than a separate kind of viewer. Kept as its own class rather
   than reusing .mv-stage because trench scans sit directly in a photo
   gallery flow (fixed clamp() height) rather than a dedicated 4:3
   viewer slot, and skip the glow/background treatment those use. */
.trench-shard {
  position: relative;
  width: 100%; height: clamp(280px, 45vh, 460px);
  margin: 10px 0 22px; display: block;
  background: rgba(0,0,0,.12);
  clip-path: polygon(8% 0, 100% 6%, 92% 100%, 0 88%);
  box-shadow: 0 14px 40px rgba(0,0,0,.45);
  --poster-color: transparent;
}
.trench-shard.cut-left  { clip-path: polygon(6% 4%, 100% 0, 94% 92%, 0 100%); }
.trench-shard.cut-right { clip-path: polygon(0 0, 94% 6%, 100% 100%, 8% 90%); }

/* legacy alias kept so any old markup still renders */
.year-photo {
  width: 100%; max-height: 460px; object-fit: cover; display: block;
  margin: 10px 0 22px;
  clip-path: polygon(8% 0, 100% 6%, 92% 100%, 0 88%);
  box-shadow: 0 14px 40px rgba(0,0,0,.45);
}
.photo-shard + .cap, .year-photo + .cap { margin-top: -10px; }
.cap { font-size: .82rem; color: var(--steel); text-align: center; margin-bottom: 24px; opacity: .85; }

.timeline-container { margin: 34px 0 6px; }
.slider {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 6px; border-radius: 10px;
  background: linear-gradient(to right, var(--primary) 0%, var(--primary) var(--fill,0%), rgba(255,255,255,.2) var(--fill,0%));
  outline: none; cursor: pointer;
}
.slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 26px; height: 26px;
  border-radius: 50%; background: var(--sand-bright); cursor: pointer;
  border: 3px solid var(--primary); box-shadow: 0 4px 12px rgba(0,0,0,.4);
  transition: transform .2s;
}
.slider::-webkit-slider-thumb:hover { transform: scale(1.12); }
.slider::-moz-range-thumb {
  width: 26px; height: 26px; border-radius: 50%; background: var(--sand-bright);
  cursor: pointer; border: 3px solid var(--primary); box-shadow: 0 4px 12px rgba(0,0,0,.4);
}
.year-labels { display: flex; justify-content: space-between; margin-top: 12px; font-size: .8rem; letter-spacing: .05em; color: var(--steel); }
.year-labels span { cursor: pointer; transition: color .2s; }
.year-labels span:hover, .year-labels span.active { color: var(--primary); }

/* ---------- team ---------- */
.team-row { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(20px, 4vw, 48px); align-items: center; margin: 40px 0; }
.team-row.flip .team-card { order: 2; }
.team-row.flip .team-img  { order: 1; }
.team-img { width: 100%; height: 340px; object-fit: cover; box-shadow: 0 10px 36px rgba(0,0,0,.45); background: #333;
  clip-path: polygon(6% 4%, 100% 0, 94% 92%, 0 100%); }
.team-row.flip .team-img { clip-path: polygon(0 0, 94% 6%, 100% 100%, 8% 90%); }
.team-card h2 { margin: 6px 0 10px; }
.team-row + .team-row { border-top: 1px solid var(--glass-brd); padding-top: 40px; }

@media (max-width: 760px) {
  .team-row, .team-row.flip { grid-template-columns: 1fr; }
  .team-row.flip .team-card, .team-row.flip .team-img { order: 0; }
  .team-img { height: 240px; }
}

/* ---------- landing (language select) ---------- */
.video-container { position: fixed; inset: 0; z-index: -1; background: #000; }
.bg-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 2.5s ease-in-out; }
.bg-video.active { opacity: 1; z-index: 1; }
.landing-overlay {
  position: fixed; inset: 0; z-index: 2;
  background: linear-gradient(180deg, rgba(0,0,0,.35), rgba(0,0,0,.6));
  display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 24px;
}
.landing-overlay h1 { margin-bottom: 8px; }
.landing-overlay .subtitle { color: var(--steel); letter-spacing: .18em; text-transform: uppercase; font-size: .8rem; margin-bottom: 36px; }
.landing-overlay .button-group { justify-content: center; }

/* ---------- mobile: bigger, more prominent 3D models ----------
   Deliberately placed at the very end of the file: earlier attempts at
   this broke because .mv-frame's base rule (margin: 18px 0 26px, which
   zeroes left/right margin) sat LATER in the file than this block did,
   and a later rule of equal specificity always wins the cascade
   regardless of whether the earlier one is inside a media query.
   Keeping mobile overrides at the true end of the stylesheet avoids
   this whole class of bug going forward.

   Uses the standard margin-only "break out to full viewport width"
   trick: margin-left/right: calc(50% - 50vw) reaches the true screen
   edges regardless of nesting, PROVIDED every ancestor is itself
   horizontally centered (.wrap uses margin:0 auto, so this holds).
   Deliberately does NOT use position:relative + left:50% — that
   combination offsets an element from its own static position, not
   from the viewport centre, and shifts it the wrong way when its
   static position is already inset by a parent's padding (which is
   exactly what .mv-stage/.mv-frame are). Also switches to a taller
   aspect-ratio and gives the hero model real viewport-relative height,
   since a portrait phone has plenty of vertical room to spend on this.
   Desktop is untouched — everything here is scoped to this breakpoint. */
@media (max-width: 760px) {
  .wrap { padding-left: 14px; padding-right: 14px; }
  .content-box, .inner-content-box { padding-left: 16px; padding-right: 16px; }

  .mv-stage, .mv-frame {
    width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
  }
  .mv-stage { aspect-ratio: 3 / 4; }   /* taller than the desktop 4:3, to use a phone's vertical room */
  .content-box model-viewer { height: 62vh; }   /* was a fixed 500px — scales with the device instead */
  .trench-shard { height: clamp(320px, 62vh, 520px); }  /* was clamp(280px, 45vh, 460px) */

  /* slightly larger hotspot touch targets — easier to tap accurately
     on a phone screen than the desktop-tuned 20px */
  .Hotspot { --s: 26px; }

  /* The shard clip-path cut looked good on desktop but awkward/cramped
     on a narrow phone screen (per direct feedback) — drop it here for
     the 3D model boxes specifically and fall back to a plain, gently
     rounded rectangle instead. Photos (.photo-shard) keep their shard
     cut on mobile; this only affects the model viewers. */
  .mv-stage, .mv-frame, .trench-shard {
    clip-path: none; border-radius: 10px; overflow: hidden;
  }
}

/* ---------- "view larger" link (opens a dedicated full-size page) ----------
   Rather than an in-page CSS expand toggle (which didn't hold up well
   in practice — see view-model.html for why), this is a plain link:
   tapping/clicking it navigates to a standalone page showing just this
   one model at full viewport size, in either orientation. Works the
   same everywhere, no JS state to get stuck.

   Positioning note: the shard clip-path cuts a triangle off each
   corner, and clip-path clips EVERYTHING painted inside the element —
   including this button. The base shard shape (used by .mv-stage/
   .mv-frame) only trims the top-right corner lightly, so a modest
   inward nudge clears it. But .trench-shard alternates between two
   MIRRORED shapes (.cut-left / .cut-right) for visual variety, and
   each one clips a DIFFERENT corner — .cut-right in particular clips
   almost the entire top-right area, not just a sliver — so nudging
   inward can't fix that variant; the button needs to sit in whichever
   corner that specific shape actually leaves intact instead. */
.fs-btn {
  position: absolute; top: 26px; right: 20px; z-index: 6;
  width: 34px; height: 34px; display: flex; align-items: center; justify-content: center;
  font-size: 1.1rem; line-height: 1; color: var(--sand-bright);
  background: rgba(20,17,12,.6); border: 1px solid var(--glass-brd); border-radius: 6px;
  cursor: pointer; backdrop-filter: blur(5px); transition: all .2s ease; padding: 0;
  text-decoration: none;
}
.fs-btn:hover { background: var(--primary); border-color: var(--primary); color: var(--ink); }

/* .cut-left's top-right corner sits exactly at the shape's true corner
   (uncut) — the default top-right position above already works there,
   just tightened back to a smaller inset since nothing needs clearing. */
.trench-shard.cut-left .fs-btn { top: 14px; right: 14px; }

/* .cut-right clips the top-right corner heavily instead — its
   top-LEFT corner is the one that sits at the true, uncut corner, so
   the button moves there for this variant specifically. */
.trench-shard.cut-right .fs-btn { top: 14px; right: auto; left: 14px; }

/* ---------- home hero: guided-tour nav controls, info panel, error ----------
   Marker styling itself reuses .Hotspot (see main.css's original
   Hotspot rules + the .active extension above) — the earlier custom
   .mv-arrow marker never rendered for reasons that resisted diagnosis,
   so this rebuild deliberately reuses the pattern already proven to
   work on results.html/field.html instead of a new custom element. */
.mv-load-error {
  text-align: center; color: var(--steel); font-size: .85rem; font-style: italic;
  margin-top: 10px;
}
.mv-load-error code {
  color: var(--sand-bright); font-family: monospace; font-style: normal;
}


.mv-nav { display: flex; gap: 14px; justify-content: center; align-items: center; margin: 18px 0 4px; }
.mv-nav-btn {
  width: 44px; height: 44px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.3rem; line-height: 1; color: var(--sand-bright);
  background: rgba(255,255,255,.07); border: 1.5px solid var(--sand-bright);
  cursor: pointer; backdrop-filter: blur(5px); transition: all .25s ease;
}
.mv-nav-btn:hover:not(:disabled) { background: var(--primary); border-color: var(--primary); color: var(--ink); transform: translateY(-2px); }
.mv-nav-btn:disabled { opacity: .3; cursor: default; }
.mv-nav-info { font-family: var(--font-display); font-style: italic; font-weight: 700; font-size: 1.1rem; }

.mv-info-panel {
  max-width: 640px; margin: 0 auto 20px; text-align: center;
  background: var(--card-bg); border: 1px solid var(--glass-brd); border-radius: 10px;
  backdrop-filter: blur(8px); padding: 18px 26px; color: var(--sand-bright);
}
.mv-info-panel[hidden] { display: none; }