/* Home: the dusk canal and the name, the services, the work, then the 3D story. */

.bar--top { position: absolute; inset: 0 0 auto; }

/* ---------- opening: the story's last frame, held still while the water moves ---------- */
/* The rendered dusk frame stands behind the live canvas, so the screen is never empty. */
.top__frame {
  background: var(--bg) url("../media/dusk-canal-1600.jpg") center / cover no-repeat;
}
@media (max-aspect-ratio: 9 / 10) {
  .top__frame { background-image: url("../media/dusk-canal-portrait-800.jpg"); }
}

/* ---------- the story: one sticky frame over a long scroll ---------- */
/* One screen of night into the marina, then the 8.05-screen day. home.js maps both ranges. */
.story { position: relative; height: 1005svh; }
.story__frame { position: sticky; top: 0; height: 100vh; /* taste-skill-ignore: fallback before svh */ height: 100svh; overflow: hidden; }
#world { position: absolute; inset: 0; width: 100%; height: 100%; background: none; }

/* Words come and go with the beat. */
[data-beat] { transition: opacity 600ms var(--ease-out), transform 900ms var(--ease-expo), visibility 0s linear 0s; }
.js .story [data-beat]:not(.on) { opacity: 0; visibility: hidden; transform: translateY(32px); pointer-events: none; transition: opacity 200ms var(--ease-out), transform 900ms var(--ease-expo), visibility 0s linear 200ms; }

/* Hero: built from the close's parts, so the story opens and ends on one frame.
   The name stands where each scene's word stands, its line where each scene's
   line sits, and the three ways to start are stacked where the close keeps them. */
.hero { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.hero > * { pointer-events: auto; }
/* The right-hand column balances the name: the mark and line above the two ways to start. */
.hero__side {
  position: absolute; right: var(--margin); bottom: clamp(1rem, 3.4vh, 2.25rem);
  width: min(28rem, 32vw); display: flex; flex-direction: column; gap: var(--space-l);
}
.hero__about { display: flex; align-items: flex-start; gap: var(--space-s); }
.hero__mark { flex: none; width: 3rem; height: 3rem; margin-top: 0.2rem; background: none; }
.hero__line { font-size: var(--step-lead); line-height: 1.35; font-weight: 500; text-wrap: pretty; }
.hero__actions { display: flex; flex-direction: column; align-items: stretch; gap: var(--space-xs); }
.hero__name {
  position: absolute; left: var(--margin); bottom: var(--word-bottom);
  font-family: var(--font-display); font-weight: 900; text-transform: uppercase;
  font-size: var(--word); line-height: 0.8; letter-spacing: -0.05em; margin-left: -0.03em; white-space: nowrap;
}
.hero__name span { display: block; }
/* The waterline cuts the name, as it cuts the mark: paper above, water below. */
.hero__above { clip-path: inset(-0.1em -0.15em 42% -0.1em); color: var(--ink); }
.hero__below { position: absolute; inset: 0; clip-path: inset(58% -0.15em -0.1em -0.1em); color: var(--water); }

/* One word per beat, low and left, nothing else. */
.beat {
  position: absolute; left: var(--margin); bottom: var(--word-bottom); z-index: 2; max-width: none;
  font-family: var(--font-display); font-weight: 900; text-transform: uppercase;
  font-size: var(--word); line-height: 0.8; letter-spacing: -0.05em; margin-left: -0.03em;
  color: var(--ink); white-space: nowrap;
}

/* The closing statement runs to two lines. */
.beat--end { font-size: min(9vw, 17vh); line-height: 0.84; }

/* The closing paths, bottom right, on the closing line's baseline. */
.cta { position: absolute; right: var(--margin); bottom: clamp(1rem, 3.4vh, 2.25rem); z-index: 3; }
.cta--end { display: flex; flex-direction: column; align-items: stretch; gap: 0.5rem; }

/* ---------- per scene: the cross-section drawn onto the picture, and a subtitle over the word ---------- */
/* No panel: the drawing joins the world's own wireframes, and the words sit on the darkened foot of the picture. */
.story { --word: min(12vw, 24vh); --word-bottom: clamp(0.75rem, 3vh, 2rem); }
/* The card is only a grouping: its drawing and its words are placed in the scene frame itself. */
.card { display: contents; }
.card__art {
  position: absolute; z-index: 3; right: var(--margin); bottom: var(--word-bottom);
  width: min(23rem, 27vw); height: auto; background: none; pointer-events: none;
}
.card__text {
  position: absolute; z-index: 3; left: var(--margin); bottom: calc(var(--word) * 0.8 + var(--word-bottom) + 1.25rem);
  display: grid; justify-items: start; gap: 0.75rem; max-width: 30ch;
}
.card__line { font-size: var(--step-lead); line-height: 1.3; font-weight: 500; }
/* One continuous yellow line under the words and the arrow: flex children do
   not inherit text-decoration, so the line is drawn by the link itself. */
.card__link {
  pointer-events: auto; position: relative; display: inline-flex; align-items: center; gap: 0.6em; min-height: 44px;
  font-weight: 500; text-decoration: none;
  transition: color var(--t-hover) var(--ease-out);
}
.card__link::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: calc(50% - 0.8em); height: 2px;
  background: var(--accent);
}
.card__link:hover { color: var(--accent); }
.card__link .arrow { transition: transform var(--t-hover) var(--ease-out); }
.card__link:hover .arrow { transform: translateX(4px); }
/* The scene's words arrive first; the drawing is plotted in after them, left to right. */
.js .story .card.on .card__text { transition: opacity 450ms var(--ease-out) 60ms, transform 600ms var(--ease-expo) 60ms; }
.js .story .card .card__text { opacity: 0; transform: translateY(16px); transition: opacity 200ms var(--ease-out); }
.js .story .card.on .card__text { opacity: 1; transform: none; }
.js .story .card .card__art { clip-path: inset(0 100% 0 0); transition: clip-path 200ms linear; }
.js .story .card.on .card__art { clip-path: inset(0 0 0 0); transition: clip-path 650ms cubic-bezier(0.33, 1, 0.68, 1) 60ms; }
@media (prefers-reduced-motion: reduce) {
  .js .story .card .card__art, .js .story .card.on .card__art { clip-path: none; transition: none; }
  .js .story .card .card__text { transform: none; }
}

/* ---------- the scene menu: one capsule that unfolds downward, a scene per stop ---------- */
.scenes {
  --dot: 3.5rem; --step: 3.25rem;
  position: absolute; z-index: 4; top: 1.5rem; right: var(--margin);
  width: var(--dot); height: var(--dot);
  transition: opacity 400ms var(--ease-out), visibility 0s linear 0s;
}
.js .story.at-hero .scenes { opacity: 0; visibility: hidden; transition: opacity 400ms var(--ease-out), visibility 0s linear 400ms; }
/* The scene's pause sits in the scene menu's column, under its button; an open menu covers it. */
.story__pause { z-index: 3; top: 5.75rem; left: auto; right: calc(var(--margin) + 0.5rem); box-shadow: 0 8px 24px rgb(3 12 24 / 0.35); /* taste-skill-ignore */ }
.scenes__toggle, .scenes__item {
  display: grid; place-items: center; width: var(--dot); height: var(--dot); border-radius: 50%;
  background: var(--surface); color: var(--ink);
}
/* A real menu floats over the scene, so it alone carries a shadow. */
.scenes__toggle { position: relative; z-index: 30; box-shadow: 0 8px 24px rgb(3 12 24 / 0.35); /* taste-skill-ignore */ transition: background-color var(--t-hover) var(--ease-out); }
.scenes__toggle:hover { background: var(--surface-2); }
.scenes .icon { width: 1.625rem; height: 1.625rem; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.scenes__icon { grid-area: 1 / 1; display: grid; transition: opacity 260ms var(--ease-out), transform 260ms var(--ease-out); }
.scenes__icon--close { opacity: 0; transform: scale(0.96) rotate(-90deg); }
.scenes.open .scenes__icon--menu { opacity: 0; transform: scale(0.96) rotate(90deg); }
.scenes.open .scenes__icon--close { opacity: 1; transform: none; }
/* Folded, the stack lets every click through to the button. */
.scenes__list { position: absolute; inset: 0; pointer-events: none; }
.scenes__list li { position: absolute; inset: 0 auto auto 0; z-index: calc(20 - var(--i)); }
/* Same colour, overlapping: open, the stops run together into one capsule below the button. */
.scenes__item {
  position: relative; text-decoration: none;
  opacity: 0; visibility: hidden; transform: translateY(0);
  transition: transform 320ms cubic-bezier(0.4, 0, 0.2, 1), opacity 320ms var(--ease-out), color var(--t-hover) var(--ease-out), visibility 0s linear 320ms;
}
.scenes.open .scenes__item {
  opacity: 1; visibility: visible; pointer-events: auto;
  transform: translateY(calc((var(--i) + 1) * var(--step)));
  transition: transform 320ms cubic-bezier(0.4, 0, 0.2, 1), opacity 260ms var(--ease-out), color var(--t-hover) var(--ease-out), visibility 0s;
  transition-delay: calc(var(--i) * 18ms);
}
.scenes__item:hover, .scenes__item:focus-visible { color: var(--accent); }
.scenes__item[aria-current="step"] { color: var(--accent); }
.scenes__item:focus-visible { outline-offset: -4px; }
/* Where it goes, named beside the stop on hover or focus. */
.scenes__label {
  position: absolute; right: calc(100% + 0.5rem); top: 50%;
  padding: 0.5rem 0.85rem; white-space: nowrap;
  background: var(--surface); color: var(--ink); font-weight: 500; font-size: var(--step-small);
  opacity: 0; transform: translate(0.4rem, -50%); pointer-events: none;
  transition: opacity var(--t-hover) var(--ease-out), transform var(--t-hover) var(--ease-out);
}
.scenes__item:hover .scenes__label, .scenes__item:focus-visible .scenes__label { opacity: 1; transform: translate(0, -50%); }
/* Touch screens have no hover: open, every stop shows its name. */
@media (hover: none) {
  .scenes.open .scenes__label { opacity: 1; transform: translate(0, -50%); }
}

/* ---------- intro: the words on the left, the barge on film on the right, then one place to ask ---------- */
.intro { padding-top: clamp(5rem, 9vw, 8.5rem); }
.intro__grid {
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter);
  align-items: center;
}
/* The words: title, statement and note on one left edge, spaced as one block. */
.intro__words { grid-column: 1 / span 6; display: grid; align-content: center; justify-items: start; padding-right: var(--space-xl); }
.intro__title { font-size: clamp(2.5rem, 0.9rem + 4.1vw, 5.25rem); line-height: 0.88; }
.intro__note {
  margin-top: clamp(1.25rem, 2vw, 2rem);
  font-size: clamp(1.25rem, 0.95rem + 0.8vw, 1.75rem); line-height: 1.25; font-weight: 500; max-width: 24ch; text-wrap: balance;
}
.intro__side {
  margin-top: clamp(1.5rem, 2.6vw, 2.25rem); padding-top: clamp(1.25rem, 2vw, 1.75rem); max-width: 46ch;
  border-top: 1px solid var(--line); color: var(--muted); line-height: 1.6; text-wrap: pretty;
}
/* The barge, in its own frame: a light cyan-to-navy plate around crisp footage. */
.intro__film {
  grid-column: 7 / -1; margin: 0; padding: clamp(0.875rem, 1.4vw, 1.25rem);
  border: 2px solid color-mix(in srgb, var(--water) 55%, transparent); border-radius: 8px;
  background: linear-gradient(155deg, color-mix(in srgb, var(--water) 42%, var(--surface)) 0%, color-mix(in srgb, var(--water) 14%, var(--surface)) 38%, var(--surface) 68%, color-mix(in srgb, var(--surface) 60%, var(--bg)) 100%); /* taste-skill-ignore: Diego asked for a light gradient on the video frame */
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.14), 0 30px 70px -34px rgb(2 10 22 / 0.9); /* taste-skill-ignore: a lit top edge, and the frame lifts off the field */
}
.intro__film-media { position: relative; overflow: hidden; border-radius: 4px; aspect-ratio: 4 / 3; background: var(--bg); box-shadow: 0 0 0 1px rgb(2 10 22 / 0.55); }
.intro__film-media::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgb(6 22 40 / 0) 55%, rgb(6 22 40 / 0.35) 100%); /* taste-skill-ignore: soft fade at the foot of the footage */
}
.intro__film video { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 45% 55%; background: none; }
.intro__film-cap { padding: clamp(0.75rem, 1.1vw, 1rem) 0.125rem clamp(0.875rem, 1.2vw, 1.125rem); font-size: var(--step-small); line-height: 1.45; color: color-mix(in srgb, var(--muted) 85%, var(--ink)); max-width: none; text-wrap: pretty; }
.facts {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(2rem, 3.5vw, 3rem) var(--gutter);
  margin-top: clamp(2.5rem, 4.5vw, 4rem);
}
.facts a { display: grid; gap: 0.35rem; align-content: start; text-decoration: none; }
.facts__drawing {
  width: 100%; height: auto; aspect-ratio: 8 / 5; margin-bottom: 0.9rem;
  background: var(--surface); border-top: 2px solid color-mix(in srgb, var(--water) 45%, transparent);
  transition: border-color var(--t-hover) var(--ease-out);
}
.facts a:hover .facts__drawing { border-color: var(--accent); }
.facts strong { font-family: var(--font-display); font-weight: 900; text-transform: uppercase; font-size: var(--step-head); line-height: 0.95; letter-spacing: -0.03em; transition: color var(--t-hover) var(--ease-out); }
.facts span { color: var(--muted); max-width: 24ch; font-size: var(--step-small); }
.facts strong { font-size: clamp(1.25rem, 2.05vw, 2.25rem); }
.facts a:hover strong { color: var(--water); }
/* The ask: a step of tone across the page, the question left, what to send and the actions right. */
.intro__ask { margin-block: var(--space-xl) var(--space-2xl); background: var(--surface); border-top: 1px solid var(--line); }
.intro__ask-in {
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); align-items: end;
  padding-block: var(--space-xl);
}
.intro__ask-title { grid-column: 1 / span 7; font-family: var(--font-display); font-weight: 900; font-size: clamp(1.75rem, 0.9rem + 2.7vw, 3.25rem); line-height: 0.95; letter-spacing: -0.03em; text-transform: uppercase; text-wrap: balance; }
.intro__ask-side { grid-column: 8 / -1; display: grid; gap: var(--space-m); }
.intro__ask-body { max-width: 40ch; text-wrap: pretty; }
.intro__ask-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-s) var(--space-l); font-weight: 500; }

/* ---------- showcase: a band of unequal panels ---------- */
.band { padding-block: 0 clamp(5rem, 9vw, 8rem); }
/* The title stands on the photos: its foot sinks into the top of the band. */
.band__title {
  position: relative; z-index: 1; margin: 0 0 -0.19em;
  font-size: min(var(--step-display), 13.4vw); line-height: 0.82; white-space: nowrap;
  pointer-events: none;
}
/* Seven real jobs in one mosaic: a wide lead, then the work up close. Each names what it shows. */
.band__grid {
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-auto-rows: clamp(11rem, 19vw, 17.5rem);
  gap: clamp(0.5rem, 0.8vw, 0.875rem);
}
.band__panel { position: relative; margin: 0; overflow: hidden; border-radius: 4px; background: var(--surface); }
.band__panel--wide { grid-column: span 6; grid-row: span 2; }
.band__panel--mid { grid-column: span 4; grid-row: span 2; }
.band__panel--tall { grid-column: span 2; grid-row: span 2; }
.band__panel--sq { grid-column: span 3; }
.band__panel img { width: 100%; height: 100%; object-fit: cover; background: none; transition: transform 700ms var(--ease-out); }
.band__panel:hover img { transform: scale(1.04); }
.band__panel::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgb(6 22 40 / 0) 55%, rgb(6 22 40 / 0.78) 100%); /* taste-skill-ignore: scrim under the caption */
}
.band__panel figcaption {
  position: absolute; z-index: 1; left: 0.9rem; right: 0.9rem; bottom: 0.75rem;
  font-size: var(--step-small); font-weight: 500; line-height: 1.3; color: var(--ink);
}
.band__caption { margin-top: 1.25rem; max-width: none; }

@media (max-width: 860px) {
  .story { --word: 17vw; }
  /* Phones: the line, then the three ways to start, then the name, as one column on the foot of the frame. */
  /* Phones: the line, the ways to start, then the name, as one column on the foot of the frame. */
  .hero { display: flex; flex-direction: column; justify-content: flex-end; gap: 1.25rem; padding: 0 var(--margin) var(--word-bottom); }
  .hero__side { position: static; width: auto; gap: 1.25rem; }
  .hero__about { gap: 0.75rem; }
  .hero__mark { width: 2.5rem; height: 2.5rem; }
  .hero__line { font-size: 1.125rem; }
  .hero__name { position: relative; left: auto; bottom: auto; order: 3; }
  .hero__actions .btn { min-height: 44px; padding-block: 0.6rem; }
  .beat { font-size: var(--word); }
  .beat--end { font-size: 13vw; }
    .cta--end { right: var(--margin); bottom: calc(13vw * 0.84 * 2 + 2.75rem); flex-direction: column; }
  .cta--end .btn { min-height: 44px; padding-block: 0.6rem; }
  /* Phones: the subtitle alone, over the word; the drawings wait on the Services page. */
  .card__art { display: none; }
  .card__text { right: var(--margin); max-width: none; bottom: calc(var(--word) * 0.8 + var(--word-bottom) + 1rem); gap: 0.25rem; }
  .card__line { font-size: 1.125rem; }
  .scenes { --dot: 3rem; --step: 2.85rem; top: 0.75rem; }
  .story__pause { top: 4.75rem; right: calc(var(--margin) + 0.25rem); }
  /* Phones: title, statement, the film, the note, then the ask. */
  .intro__grid, .intro__ask-in { grid-template-columns: minmax(0, 1fr); }
  .intro__words, .intro__film, .intro__ask-title, .intro__ask-side { grid-column: 1; }
  .intro__words { display: contents; }
  .intro__title { order: 1; } .intro__note { order: 2; margin-top: var(--space-s); }
  .intro__film { order: 3; margin-top: var(--space-l); } .intro__side { order: 4; margin-top: var(--space-l); padding-top: 0; border-top: 0; }
  .intro__ask-side { margin-top: var(--space-m); }
  .intro__ask-actions { flex-direction: column; align-items: stretch; }
  .intro__ask-actions .btn { width: 100%; }
  .facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 2rem; }
  .facts__drawing { margin-bottom: 0.5rem; }
  /* Sized to the column so the longest word, CONSTRUCTION or CONSTRUCCIÓN, fits on one line. */
  .facts strong { font-size: min(1.625rem, 5vw); }
  .facts span { font-size: 1rem; }
  .band__title { font-size: 12.6vw; }
  .band__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 42vw; }
  .band__panel--wide { grid-column: span 2; grid-row: span 1; }
  .band__panel--mid, .band__panel--tall, .band__panel--sq { grid-column: span 1; grid-row: span 1; }
  .band__panel--mid { grid-column: span 2; }
  .band__panel:last-child { grid-column: span 2; }
}

@media (prefers-reduced-motion: reduce) {
  .js .story [data-beat] { transition: none; transform: none; }
  /* Reduced motion: beats swap without travel; an inactive one leaves the layout entirely. */
  .js .story [data-beat]:not(.on) { transition: none; transform: none; display: none; }
  .band__panel img { transition: none; }
}

/* Without WebGL or script the opening shows the rendered still and the story steps aside. */
.story.no-world, html:not(.js) .story { height: 100vh !important; height: 100svh !important; min-height: 34rem; }
.story.no-world .story__frame, html:not(.js) .story__frame { position: relative; height: 100%; }
.story.no-world [data-beat], .story.no-world .scenes, .story.no-world #world,
html:not(.js) .story [data-beat], html:not(.js) .scenes, html:not(.js) #world { display: none; }
.story.no-world .hero { opacity: 1 !important; visibility: visible !important; }
@media (prefers-reduced-motion: reduce) { .story { height: 920svh; } }
/* The story's cards carry the services; the grid of drawings shows only when the story cannot. */
.js body:has(.story:not(.no-world)) .intro .facts { display: none; }



/* Keep Spanish story words and their adjacent actions inside the reserved bands. */
/* Spanish story words are shorter and share the English size. */
html:lang(es) .band__title { font-size: min(var(--step-display), 12.3vw); }
@media (max-width: 860px) {
  html:lang(es) .beat:not(.beat--end) { font-size: 16vw; }
  html:lang(es) .band__title { font-size: 11.6vw; }
  html:lang(es) .beat--end { font-size: 12vw; }
}
