/* ==========================================================================
   Clicke — seven-scene vertical scroll site
   Geometry follows design/ and README.md verbatim. Every dimension inside a
   stage is expressed in cqw (1cqw = 1% of stage width) so the design scales
   as one unit.
   ========================================================================== */

:root {
  --yellow: #FEDC14;
  --amber:  #D88D26;
  --blue:   #3285C2;
  --lblue:  #A9D4EC;
  --muted:  #6C9CC0;
  --red:    #E4432F;
  --paper:  #f2efe9;

  /* The 16:9 stage. Width is capped so the stage never exceeds the viewport
     height at 16:9; height comes from aspect-ratio, and the scene takes its
     height from the stage. That keeps every scene exactly one stage tall so
     the seven stages stack edge to edge and the ribbon stays continuous.
     Note 100% (not 100vw) — vw includes the scrollbar and would push the
     stage off 16:9. */
  --stage-w: min(100%, calc(100vh * 16 / 9));

  /* What the fixed header occupies: its top margin plus the mark. Scene pages
     letterbox under it by design; document pages have to push their column
     clear of it, and they have no stage to measure in cqw. */
  --header-h: calc(var(--stage-w) * 0.057);

  --ribbon-opacity: 0.7;
  --ribbon-glass-opacity: 0.182; /* ribbon x 0.26 */
}

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;

  /* One continuous gradient for the whole page, in place of seven per-scene
     background blocks with a hard edge at every boundary. It runs through the
     same seven colours in the same order, each landing on its own scene's
     centre — scene N at (N - 0.5)/7 of the page — so every scene boundary
     falls mid-ramp and no edge exists to be seen.

     On the root element the positioning area is the document while the
     painting area is the whole canvas, so the end colours also extend into
     overscroll at both ends. */
  background:
    linear-gradient(to bottom,
      #2f3235  7.142857%,
      #343636 21.428571%,
      #393a38 35.714286%,
      #3e3e39 50%,
      #42413a 64.285714%,
      #47453c 78.571429%,
      #4c493d 92.857143%) no-repeat;
  background-color: #2f3235;
}

body {
  margin: 0;
  padding: 0;
  color: var(--paper);
  font-family: Jost, 'Helvetica Neue', Helvetica, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { color: var(--lblue); text-decoration: none; transition: color 180ms ease; }
a:hover { color: var(--yellow); }

/* Off-screen store for the shared SVG geometry referenced by <use>. */
.defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* --------------------------------------------------------------------------
   Scene + stage
   -------------------------------------------------------------------------- */

/* How far down the stage the panel starts. It lives on the scene rather than
   on the panel because the panel's through-glass ribbon copy has to cancel
   exactly this number: one value, read twice, so the two can never drift. */
.scene {
  --panel-top: 9.4cqw;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  overflow: hidden;
}

/* No background: the page gradient shows through. --scene-bg survives on each
   section, but only as the fill for the desk-screen backings that have to
   occlude the ribbon behind them. */
.stage {
  position: relative;
  width: var(--stage-w);
  aspect-ratio: 16 / 9;
  container-type: size;
  overflow: hidden;
}

/* Shared furniture ------------------------------------------------------- */

/* The warm glow and the yellow wash light the top of the page once, above the
   hero — they are not scene furniture and no longer repeat.

   They sit outside the stage because the stage's size containment makes it a
   stacking context, which would isolate their screen blend and leave them
   compositing against nothing. Out here the backdrop is the page gradient
   itself, which is what they are meant to lighten. The trade is that cqw is
   not available, so the wrapper takes the stage's width and the two layers
   take their heights from percentage padding — which resolves against that
   same width, giving the design's 7.5% and 2.6% of the stage. */
.toplight {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  width: var(--stage-w);
  margin: 0 auto;
  pointer-events: none;
}

.glow,
.wash {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 0;
  mix-blend-mode: screen;
}

.glow {
  padding-top: 7.5%;
  background: radial-gradient(70% 100% at 50% 0%,
    rgba(228,150,44,0.62) 0%,
    rgba(216,141,38,0.34) 34%,
    rgba(216,141,38,0.10) 60%,
    rgba(0,0,0,0) 82%);
}

.wash {
  padding-top: 2.6%;
  background: linear-gradient(to bottom,
    rgba(254,220,20,0.22) 0%,
    rgba(216,141,38,0.08) 50%,
    rgba(0,0,0,0) 100%);
}

.floor {
  position: absolute;
  left: 7cqw;
  right: 7cqw;
  top: 48.86cqw;
  height: 0.19cqw;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(to right,
    rgba(169,212,236,0) 0%,
    rgba(169,212,236,0.42) 1.2%,
    rgba(169,212,236,0.42) 98.8%,
    rgba(169,212,236,0) 100%);
}

/* --------------------------------------------------------------------------
   Ribbon
   -------------------------------------------------------------------------- */

.ribbon-layer {
  position: absolute;
  inset: 0;
  z-index: 1;
  opacity: var(--ribbon-opacity);
  pointer-events: none;
}

.ribbon {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* Each ribbon SVG carries both runs: the scene's authored desktop path and the
   straight portrait one. Only the breakpoint decides which is drawn, so both
   copies of a scene's ribbon — real and through-glass — switch together. */
.ribbon > .rb-m { display: none; }

/* Draw. Every ribbon path carries pathLength="1", so a single dash of length 1
   spans the whole path whatever its true length, and the offset is exactly the
   undrawn fraction. stroke-dasharray and stroke-dashoffset are inherited SVG
   properties, so setting them on the <svg> reaches the paths inside the <use>
   shadow tree, where a selector could not.

   --draw is written by app.js from total page scroll progress. Both copies of
   a scene's ribbon — the real one and the clipped copy inside the glass — are
   written in the same frame from the same number, so they cannot desync.

   Without .js-anim (no script, or reduced motion) neither property applies and
   the ribbon renders whole. */
.js-anim .ribbon {
  stroke-dasharray: 1 1;
  stroke-dashoffset: calc(1 - var(--draw, 0));
}

/* --------------------------------------------------------------------------
   Glass panel
   -------------------------------------------------------------------------- */

.panel {
  position: absolute;
  top: var(--panel-top);
  width: 57cqw;
  z-index: 5;
  border-radius: 1.1cqw;
  border: 1px solid rgba(255,255,255,0.10);
  background: rgba(255,255,255,0.055);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: 0 1.4cqw 4cqw rgba(0,0,0,0.22);
  padding: 2.6cqw 3.6cqw;
  overflow: hidden;
}

.panel--left  { left: 5cqw; }
.panel--right { right: 5cqw; text-align: right; }
.panel--hero  { padding: 3.2cqw 3.6cqw 3.4cqw; }

/* The panels that carry more than a heading and a list start 2.4cqw higher,
   so they still close above the scene's own figures: CONTACTO for the form,
   the consent and the disclosure, the four service panels for the way into
   their own pages. */
.scene--service,
#contacto { --panel-top: 7cqw; }

/* Second copy of the scene's ribbon, clipped by the panel, reading as the
   ribbon glowing faintly through frosted glass. Offsets cancel the panel's
   own inset and border so it lands exactly over the stage. */
.panel__ribbon {
  position: absolute;
  top: calc(-1 * var(--panel-top) - 1px);
  width: 100cqw;
  height: 56.25cqw;
  z-index: 0;
  opacity: var(--ribbon-glass-opacity);
  pointer-events: none;
}

.panel--left  > .panel__ribbon { left:  calc(-5cqw - 1px); }
.panel--right > .panel__ribbon { right: calc(-5cqw - 1px); }

.panel__body { position: relative; z-index: 1; }

/* --------------------------------------------------------------------------
   Panel typography
   -------------------------------------------------------------------------- */

.heading {
  margin: 0;
  font-weight: 200;
  font-size: 5.2cqw;
  line-height: 1.14;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-wrap: pretty;
}

.heading--stack {
  display: flex;
  flex-direction: column;
  gap: 0.4cqw;
}

.heading em {
  font-style: normal;
  font-weight: 500;
  color: var(--lblue);
}

.tagline {
  margin: 1cqw 0 0;
  max-width: 30cqw;
  font-weight: 400;
  font-size: 1.7cqw;
  letter-spacing: 0.04em;
  line-height: 1.35;
  color: rgba(169,212,236,0.85);
}

.panel--right .tagline { margin-left: auto; }

.tagline--hero {
  max-width: none;
  white-space: nowrap;
  line-height: 1.3;
}

.bullets {
  margin: 1.4cqw 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.7cqw;
}

.panel--right .bullets { align-items: flex-end; }

.bullets li {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.85cqw;
  font-weight: 300;
  font-size: 1.45cqw;
  letter-spacing: 0.05em;
  color: rgba(242,239,233,0.82);
}

.panel--right .bullets li { flex-direction: row-reverse; }

.bullets svg {
  width: 0.95cqw;
  height: 0.95cqw;
  display: block;
  flex: none;
}

/* --------------------------------------------------------------------------
   Section entry

   Everything a scene holds except its ribbon rises a little and fades in when
   the scene reaches the viewport. app.js marks the elements and sets each
   one's delay, so the stagger follows document order — the panel first, then
   the world assembling around it — and adds .is-in to the scene once.

   The ribbon is deliberately excluded: it is scroll-driven, and a scene-entry
   transition on top of that would fight the draw.
   -------------------------------------------------------------------------- */

.js-anim .enter {
  opacity: 0;
  transform: translateY(2cqw);
  transition:
    opacity   1500ms cubic-bezier(0.22, 0.61, 0.36, 1),
    transform 1500ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.js-anim .is-in .enter {
  opacity: 1;
  transform: none;
}

/* --------------------------------------------------------------------------
   Scene content: figures, desks, accessories
   -------------------------------------------------------------------------- */

/* Horizontal placement rides in on --x from the markup rather than an inline
   left, so the portrait layout can reposition these without having to outrank
   an inline style. */
.figure,
.desk { left: var(--x); }

.figure {
  position: absolute;
  top: 39.86cqw;
  width: 4.19cqw;
  height: 9cqw;
  z-index: 3;
  display: block;
  overflow: visible;
}

/* ASISTENCIA and CONTACTO mount slightly larger and a touch lower. */
.figure--lg {
  top: 40.22cqw;
  width: 4.44cqw;
  height: 9.54cqw;
}

.figure--front { z-index: 4; }
.figure--lead  { z-index: 5; }

.desk {
  position: absolute;
  top: 40.39cqw;
  width: 19.5cqw;
  height: 9.3cqw;
  z-index: 3;
  display: block;
}

.flow-nodes {
  position: absolute;
  left: 6cqw;
  top: 33.5cqw;
  width: 30cqw;
  height: 5.2cqw;
  z-index: 3;
  display: block;
}

.scatter-grid {
  position: absolute;
  left: 62.8cqw;
  top: 35.85cqw;
  width: 30cqw;
  height: 2.55cqw;
  z-index: 3;
  display: block;
}

.assist-rings {
  position: absolute;
  left: 5.6cqw;
  top: 33.5cqw;
  width: 15cqw;
  height: 3.3cqw;
  z-index: 3;
  display: block;
  overflow: visible;
}

.contacto-mark {
  position: absolute;
  left: 66.5cqw;
  top: 5.6cqw;
  width: 11cqw;
  height: 11cqw;
  z-index: 3;
  display: block;
  overflow: visible;
}

/* --------------------------------------------------------------------------
   Sticky header — one for the whole page. The mark's centre knockout is a
   real hole (SVG mask), so it reads correctly over every scene background.
   -------------------------------------------------------------------------- */

.header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 60;
  display: flex;
  justify-content: center;
  pointer-events: none;
}

.header__stage {
  width: var(--stage-w); /* matches the scene stage, so cqw units line up */
  container-type: inline-size;
  display: flow-root;
}

/* The row spans the stage so the nav can sit against its right edge, while
   the two ends stay click-through: the header is a fixed overlay and must not
   swallow clicks meant for the scene behind it. */
.header__row {
  margin: 3.4cqw 5cqw 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2cqw;
}

.header__bar {
  width: max-content;
  display: flex;
  align-items: center;
  gap: 1.05cqw;
  pointer-events: auto;
}

.nav {
  display: flex;
  align-items: center;
  gap: 2.2cqw;
  pointer-events: auto;
}

/* Paper at 0.85 rather than full strength: the nav is a way out of the page,
   not part of what it says. */
.nav__link {
  font-weight: 300;
  font-size: 1.15cqw;
  letter-spacing: 0.1em;
  line-height: 1;
  white-space: nowrap;
  color: rgba(242,239,233,0.85);
}

.nav__link:hover { color: var(--yellow); }

/* The page you are already on: full strength rather than a second colour. */
.nav__link[aria-current="page"] { color: var(--paper); }

.header__mark {
  width: 2.3cqw;
  height: 2.3cqw;
  display: block;
  overflow: visible;
}

.header__word {
  font-size: 1.05cqw;
  font-weight: 400;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: var(--paper);
  line-height: 1;
}

.header__bar:hover .header__word { color: var(--paper); }

/* --------------------------------------------------------------------------
   Contact form
   -------------------------------------------------------------------------- */

.form {
  margin-top: 1.8cqw;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.75cqw;
}

.form__field {
  width: 31cqw;
  height: 3.3cqw;
  border-radius: 1.65cqw;
  border: 1px solid rgba(169,212,236,0.30);
  background: rgba(169,212,236,0.055);
  padding: 0 1.6cqw;
  display: block;
  font-family: inherit;
  font-weight: 300;
  font-size: 1.4cqw;
  letter-spacing: 0.05em;
  color: var(--paper);
  transition: border-color 180ms ease;
}

.form__field::placeholder { color: rgba(242,239,233,0.48); opacity: 1; }
.form__field:focus { outline: none; border-color: rgba(169,212,236,0.60); }

/* Kept to the same pill as the inputs, per the design. The caret still
   scrolls into view; no scrollbar is allowed to break the pill. */
textarea.form__field {
  padding: 0.85cqw 1.6cqw;
  line-height: 1.6cqw;
  resize: none;
  overflow: hidden;
  scrollbar-width: none;
}

textarea.form__field::-webkit-scrollbar { display: none; }

/* Consent, in the fields' own materials: the same hairline and tinted glass,
   filled light blue when it is given. The label is the hit area, so the text
   is as clickable as the box. */
.form__consent {
  display: flex;
  align-items: flex-start;
  gap: 0.85cqw;
  max-width: 31cqw;
  font-weight: 300;
  font-size: 1.15cqw;
  letter-spacing: 0.04em;
  line-height: 1.45;
  color: rgba(242,239,233,0.82);
  cursor: pointer;
}

.form__check {
  position: relative;
  top: 0.12cqw;          /* optically level with the first line's x-height */
  flex: none;
  width: 1.3cqw;
  height: 1.3cqw;
  margin: 0;
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid rgba(169,212,236,0.30);
  border-radius: 0.32cqw;
  background: rgba(169,212,236,0.055);
  cursor: pointer;
  transition: border-color 180ms ease, background 180ms ease;
}

.form__check:checked {
  background: var(--lblue);
  border-color: var(--lblue);
}

/* The tick is drawn from two borders rather than set in a glyph, so it scales
   with the box and needs no second font. */
.form__check:checked::after {
  content: '';
  position: absolute;
  left: 0.5cqw;
  top: 0.3cqw;      /* the tick's own centre, a hair high as a tick reads best */
  width: 0.3cqw;
  height: 0.62cqw;
  border: solid #2f3235;
  border-width: 0 0.16cqw 0.16cqw 0;
  transform: rotate(45deg);
}

.form__check:focus-visible {
  outline: 1px solid rgba(169,212,236,0.60);
  outline-offset: 0.2cqw;
}

.form__submit {
  margin-top: 0.7cqw;
  height: 3.3cqw;
  border: 0;
  border-radius: 1.65cqw;
  background: var(--lblue);
  padding: 0 2.6cqw;
  font-family: inherit;
  font-weight: 400;
  font-size: 1.4cqw;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #2f3235;
  cursor: pointer;
  transition: background 180ms ease;
}

.form__submit:hover { background: var(--yellow); }

.form__submit:disabled { opacity: 0.6; cursor: default; }
.form__submit:disabled:hover { background: var(--lblue); }

/* Errors show on the field itself, and outrank :focus so the border does not
   go quiet the moment the visitor returns to fix it. */
.form__field--error,
.form__field--error:focus,
.form__check--error,
.form__check--error:focus { border-color: var(--red); }

.form__status {
  margin: 0.4cqw 0 0;
  font-weight: 400;
  font-size: 1.15cqw;
  letter-spacing: 0.04em;
  line-height: 1.35;
  color: rgba(169,212,236,0.85);
}

.form__status--error { color: var(--red); }

/* Honeypot — kept out of sight and out of the tab order. */
.form__botcheck {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* The disclosure speaks in the contact line's voice — same size, same colour —
   but keeps to the form's width so it reads as part of it rather than as the
   next thing down the panel. */
.form__note {
  margin: 1cqw 0 0;
  max-width: 31cqw;
  font-weight: 400;
  font-size: 1.15cqw;
  letter-spacing: 0.04em;
  line-height: 1.35;
  color: rgba(169,212,236,0.85);
}

/* The way into a service's own page. The tagline's voice, a size down: it
   belongs to the panel's text rather than to the list above it. */
.panel__more {
  display: inline-block;
  margin-top: 1.4cqw;
  font-weight: 400;
  font-size: 1.25cqw;
  letter-spacing: 0.04em;
  line-height: 1.35;
  color: rgba(169,212,236,0.85);
}

.panel__more:hover { color: var(--yellow); }

.contact-line {
  margin: 1.6cqw 0 0;
  font-weight: 400;
  font-size: 1.15cqw;
  letter-spacing: 0.04em;
  line-height: 1.35;
  color: rgba(169,212,236,0.85);
}

/* --------------------------------------------------------------------------
   Reduced motion. app.js never adds .js-anim in this mode, so the ribbon is
   already whole and the contents are already in place; what is left is the
   page's own transitions.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  a,
  .nav__link,
  .panel__more,
  .form__field,
  .form__check,
  .form__submit { transition: none; }
}

/* --------------------------------------------------------------------------
   Mobile portrait

   The 16:9 stage is abandoned rather than letterboxed: the stage takes the
   whole portrait viewport, one scene per screen, the seven still in order and
   still exactly equal in height — which is what keeps the gradient's stops on
   their scenes' centres and the ribbon's seven shares equal.

   Everything stays in cqw, now 1% of the phone's width, so the design still
   scales as one unit. What cannot carry over are the ratios: 5.2cqw of a
   390px stage is a 20px heading. Each role gets its portrait value instead.
   -------------------------------------------------------------------------- */

@media (max-width: 760px) and (orientation: portrait) {

  :root { --stage-w: 100%; }

  .stage {
    width: 100%;
    height: 100vh;
    height: 100svh;   /* discounts the mobile browser's retracting chrome */
    aspect-ratio: auto;
  }

  /* --- ribbon ----------------------------------------------------------- */

  .ribbon > .rb-d { display: none; }
  .ribbon > .rb-m { display: block; }

  /* --- header ----------------------------------------------------------- */

  :root { --header-h: calc(var(--stage-w) * 0.145); }

  .header__row { margin: 6cqw 5cqw 0; gap: 3cqw; }
  .header__bar { gap: 3cqw; }

  /* Two links and a wordmark have to share one phone-width row, so the links
     take their touch height from padding rather than from type size. */
  .nav { gap: 3.5cqw; }

  .nav__link {
    position: relative;
    font-size: 3.1cqw;
    letter-spacing: 0.08em;
    padding: 2.6cqw 0;
  }

  /* A thumb needs more than the type does. The hit area grows upward, into
     the empty strip between the nav and the top of the screen, so the touch
     target reaches 51px without the header growing a pixel taller and
     reaching down into the CONTACTO panel. */
  .nav__link::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: -4cqw;
    bottom: -2cqw;
  }
  .header__mark { width: 8cqw; height: 8cqw; }
  .header__word { font-size: 3.4cqw; letter-spacing: 0.3em; }

  /* --- panel: full width, one side, no zig-zag -------------------------- */

  .scene { --panel-top: 20cqw; }

  .panel,
  .panel--left,
  .panel--right {
    left: 3.5cqw;
    right: 3.5cqw;
    width: auto;
    padding: 6cqw 5.5cqw 7cqw;
    border-radius: 3.5cqw;
    text-align: left;
  }

  .panel--hero { padding: 7cqw 5.5cqw 8cqw; }

  /* The alternating sides collapse, so the right-hand panels' mirrored
     alignment has to come back off. */
  .panel--right .tagline { margin-left: 0; }
  .panel--right .bullets { align-items: flex-start; }
  .panel--right .bullets li { flex-direction: row; }

  /* The through-glass copy still has to land exactly over the stage, so it
     cancels the portrait inset and matches the portrait stage box. */
  .panel--left > .panel__ribbon,
  .panel--right > .panel__ribbon {
    left: calc(-3.5cqw - 1px);
    right: auto;
    width: 100cqw;
    height: 100svh;
  }

  /* The service panels come back down to the shared portrait inset — there is
     room for the link here. CONTACTO keeps its own. */
  #contacto { --panel-top: 12cqw; }

  /* --- type ------------------------------------------------------------- */

  .heading { font-size: 11cqw; letter-spacing: 0.14em; line-height: 1.1; }
  .heading--stack { gap: 1cqw; }

  .tagline { margin-top: 2.4cqw; max-width: none; font-size: 4.1cqw; }
  .tagline--hero { white-space: normal; }   /* no room for one line here */

  .panel__more { margin-top: 3.5cqw; font-size: 3.4cqw; }

  .bullets { margin-top: 4cqw; gap: 2.2cqw; }
  .bullets li { font-size: 3.6cqw; gap: 2.6cqw; }
  .bullets svg { width: 2.4cqw; height: 2.4cqw; }

  /* --- scene contents --------------------------------------------------- */

  /* The delegation and innovation choruses have nowhere to stand beside a
     full-width panel. The trio that carries the narrative stays, and a single
     desk stands in for the row. */
  .figure:has(use[href="#fig-muted"]) { display: none; }
  .desk ~ .desk { display: none; }

  /* Every scene's trio is one of each treatment, so the three place uniformly
     across all seven without per-scene values. */
  .figure:has(use[href="#fig-outline-yellow"]) { left: 30cqw; }
  .figure:has(use[href="#fig-protagonist"])    { left: 47.4cqw; }
  .figure:has(use[href="#fig-outline-blue"])   { left: 64.8cqw; }

  .figure {
    top: auto;
    bottom: 7cqw;
    width: 14cqw;
    height: 30cqw;
  }

  /* ASISTENCIA and CONTACTO keep the pair stepping forward: larger, lower. */
  .figure--lg {
    bottom: 5.8cqw;
    width: 14.85cqw;
    height: 31.8cqw;
  }

  .floor {
    top: auto;
    bottom: 6.5cqw;      /* its top edge meets the figures' footing */
    left: 14cqw;
    right: 5cqw;
    height: 0.5cqw;
  }

  .desk {
    top: auto;
    bottom: 42cqw;
    left: 27cqw;
    width: 46cqw;
    height: 22cqw;
  }

  /* INNOVAR is the peak of the narrative and cannot collapse to one desk —
     that reads as MEDIR. Its three workstations stay, as a row receding up and
     to the right: each one smaller and higher than the last, overlapping the
     way a room does. Later rules carry more class weight than earlier ones, so
     the three cascade onto the same elements in order. */
  #innovar .desk ~ .desk { display: block; }

  /* One worker at the front desk, so the row reads as workstations in use
     rather than empty furniture. The two behind stay away: three more figures
     in that band, at phone width, is mush. Scaled and seated off the front
     desk's own box, in the proportions the desktop scene uses — and left ahead
     of the desk in document order, so the desk still paints over the body. */
  #innovar .figure:has(use[href="#fig-muted"]) {
    display: block;
    left: 25cqw;
    bottom: 39.7cqw;
    width: 8.6cqw;
    height: 18.4cqw;
  }

  #innovar .figure:has(use[href="#fig-muted"]) ~ .figure:has(use[href="#fig-muted"]) {
    display: none;
  }

  #innovar .desk {
    left: 20cqw;
    bottom: 38cqw;
    width: 40cqw;
    height: 19cqw;
  }

  #innovar .desk ~ .desk {
    left: 38cqw;
    bottom: 47cqw;
    width: 34cqw;
    height: 16cqw;
  }

  #innovar .desk ~ .desk ~ .desk {
    left: 54cqw;
    bottom: 55cqw;
    width: 28cqw;
    height: 13.3cqw;
  }

  .flow-nodes {
    top: auto;
    bottom: 66cqw;
    left: 27cqw;
    width: 46cqw;
    height: 9cqw;
  }

  /* Lifted clear of the receding desk row below it. */
  .scatter-grid {
    top: auto;
    bottom: 72cqw;
    left: 27cqw;
    width: 46cqw;
    height: 4cqw;
  }

  .assist-rings {
    top: auto;
    bottom: 44cqw;
    left: 27cqw;
    width: 40cqw;
    height: 10cqw;
  }

  /* Down at the ribbon's lane, so the line still threads the mark's west ring
     as it does on desktop — and clear of the tall CONTACTO panel. */
  .contacto-mark {
    top: auto;
    bottom: 8cqw;
    left: 2.7cqw;
    width: 14cqw;
    height: 14cqw;
  }

  /* --- form ------------------------------------------------------------- */

  /* The tightest the form goes before the fields start to crowd: the panel
     below is what has to fit, and this is the space that is not type. */
  .form { margin-top: 3.5cqw; gap: 1.8cqw; }

  .form__field {
    width: 100%;
    height: 11cqw;
    border-radius: 5.5cqw;
    padding: 0 5cqw;
    font-size: 3.7cqw;
  }

  textarea.form__field { padding: 3cqw 5cqw; line-height: 5cqw; }

  .form__submit {
    margin-top: 2.4cqw;
    height: 11cqw;
    border-radius: 5.5cqw;
    padding: 0 8cqw;
    font-size: 3.7cqw;
  }

  .form__consent {
    max-width: none;
    gap: 2.6cqw;
    font-size: 3.1cqw;
    line-height: 1.5;
  }

  .form__check {
    top: 0.4cqw;
    width: 4.6cqw;
    height: 4.6cqw;
    border-radius: 1.1cqw;
  }

  .form__check:checked::after {
    left: 1.78cqw;
    top: 1.05cqw;
    width: 1.05cqw;
    height: 2.2cqw;
    border-width: 0 0.55cqw 0.55cqw 0;
  }

  .form__check:focus-visible { outline-offset: 0.7cqw; }

  .form__status { margin-top: 1.5cqw; font-size: 3.1cqw; }

  .form__note { margin-top: 2.5cqw; max-width: none; font-size: 3.1cqw; line-height: 1.6; }

  .contact-line { margin-top: 3.5cqw; font-size: 3.1cqw; line-height: 1.6; }

  /* The entry rise is in cqw, so it needs a portrait value to stay legible:
     the phone's stage is a fifth of the desktop's width. */
  .js-anim .enter { transform: translateY(5cqw); }
}

/* The one viewport where the closing trio cannot stand: a 16:9 phone, where
   the CONTACTO panel — with a status message showing, which is the state that
   has to fit — reaches past their heads. Every taller phone keeps them.

   13/25 = 0.52 is just under 0.5209, the width-to-height ratio at which the
   clearance turns negative, so this covers every viewport that would collide
   and none that would not. The mark and the floor line stay: the panel clears
   both even here. */
@media (max-width: 760px) and (orientation: portrait) and (min-aspect-ratio: 13/25) {
  #contacto .figure { display: none; }
}

/* Screen-reader-only labels. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Standalone pages — the 404 and the privacy notice

   Documents, not scenes: no stage, no ribbon, no container queries. They take
   the page gradient from html, which a short document simply gets in one
   screenful, and the site's type and palette. Sizing is in rem and vw rather
   than cqw, because there is no stage here for a cqw to be 1% of.
   -------------------------------------------------------------------------- */

.doc {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  justify-content: center;
  padding: 0 1.5rem clamp(3rem, 10vw, 7rem);
  padding-top: calc(var(--header-h) + clamp(1.5rem, 5vw, 3rem));
}

.doc__inner { width: 100%; max-width: 38rem; }

.doc__mark-link { display: inline-block; }

.doc__mark {
  display: block;
  width: clamp(3.25rem, 9vw, 4.5rem);
  height: clamp(3.25rem, 9vw, 4.5rem);
  overflow: visible;   /* the outer rings sit outside the 104-unit box */
}

.doc__title {
  margin: clamp(1.75rem, 5vw, 2.75rem) 0 0;
  font-weight: 200;
  font-size: clamp(1.8rem, 6.5vw, 2.9rem);
  line-height: 1.14;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-wrap: pretty;
  color: var(--paper);
}

.doc .doc__lead {
  margin: 1.15rem 0 0;
  max-width: 30rem;
  font-weight: 400;
  font-size: clamp(1rem, 2.6vw, 1.15rem);
  letter-spacing: 0.04em;
  line-height: 1.5;
  color: rgba(169,212,236,0.85);
}

/* Section headings are the bullet labels' weight rather than the heading's:
   this is a page to be read, not a scene to be looked at. */
.doc h2 {
  margin: clamp(1.9rem, 5vw, 2.6rem) 0 0;
  font-weight: 400;
  font-size: clamp(0.9rem, 2.3vw, 1rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--lblue);
}

.doc h2 + p { margin-top: 0.7rem; }

.doc p {
  margin: 0.9rem 0 0;
  font-weight: 300;
  font-size: clamp(1rem, 2.5vw, 1.05rem);
  letter-spacing: 0.02em;
  line-height: 1.7;
  color: rgba(242,239,233,0.82);
}

.doc .doc__updated {
  margin-top: clamp(2.2rem, 6vw, 3rem);
  font-size: 0.9rem;
  color: rgba(242,239,233,0.48);
}

.doc .doc__home {
  margin-top: clamp(2.2rem, 6vw, 3rem);
  font-weight: 400;
  font-size: 0.9rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   Quiénes somos — the two profiles

   The scenes' glass panel, rebuilt in a document's units, and the outline
   figures' halo ring at a portrait's scale.
   -------------------------------------------------------------------------- */

.doc__inner--wide { max-width: 62rem; }

/* The column is wide enough for two cards, which is wider than a line of
   text wants to be: the intro keeps its own measure, around 70 characters. */
.doc__inner--wide .doc__lead { max-width: 36rem; }

.profiles {
  margin-top: clamp(2.2rem, 6vw, 3.2rem);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.2rem, 3vw, 1.8rem);
}

.profile,
.sheet {
  border-radius: 1rem;
  border: 1px solid rgba(255,255,255,0.10);
  background: rgba(255,255,255,0.055);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: 0 1rem 3rem rgba(0,0,0,0.22);
  padding: clamp(1.6rem, 4vw, 2.2rem);
}

/* The ring is drawn outside the photo, so the margin leaves it room rather
   than letting it crop against the panel's padding. */
.profile__portrait {
  position: relative;
  width: 8.5rem;
  height: 8.5rem;
  margin: 0.6rem auto 0;
}

.profile__photo {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}

/* The halo the outline figures wear: thin, clear of what it surrounds, and
   one colour per person — amber and deep blue, as the bullet rings run. */
.profile__portrait::after {
  content: '';
  position: absolute;
  inset: -0.6rem;
  border-radius: 50%;
  border: 3px solid var(--ring);
  opacity: 0.9;
}

.profile--amber { --ring: var(--amber); }
.profile--blue  { --ring: var(--blue); }

/* Both of these outrank .doc h2 and .doc p, which would otherwise dress the
   name as a section heading and the role as body copy. */
.doc .profile__name {
  margin: clamp(1.3rem, 4vw, 1.7rem) 0 0;
  text-align: center;
  font-weight: 300;
  font-size: clamp(1.1rem, 2.8vw, 1.3rem);
  letter-spacing: 0.04em;
  line-height: 1.3;
  text-transform: none;
  color: var(--paper);
}

.doc .profile__role {
  margin: 0.6rem 0 0;
  text-align: center;
  font-weight: 400;
  font-size: 0.78rem;
  letter-spacing: 0.16em;
  line-height: 1.5;
  text-transform: uppercase;
  /* Full strength rather than the tagline's 0.85: at this size, over the
     panel's lightened glass, 0.85 lands on 4.5:1 with nothing to spare. */
  color: var(--lblue);
}

.doc .profile__role + p { margin-top: 1.3rem; }

/* One column before the cards get too narrow to read. */
@media (max-width: 720px) {
  .profiles { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------------------
   Service pages

   One per service, on the document pattern: a stepper, a title carrying its
   own S-number, and the body in glass panels down a single column.
   -------------------------------------------------------------------------- */

/* Which of the four this page is. The number beside the title takes the same
   colour as that step's ring, so the two read as one mark. */
.service--s1 { --step-colour: var(--yellow); }
.service--s2 { --step-colour: var(--amber); }
.service--s3 { --step-colour: var(--blue); }
.service--s4 { --step-colour: var(--lblue); }

/* --- the stepper --------------------------------------------------------- */

.stepper {
  display: flex;
  align-items: flex-start;
  gap: 1.4rem;
  margin-bottom: clamp(1.6rem, 4vw, 2.2rem);
}

.stepper__step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  line-height: 1;
}

/* Brand order down the four steps, the same cycle the bullet rings run. */
.stepper__step:nth-child(1) { --step: var(--yellow); }
.stepper__step:nth-child(2) { --step: var(--amber); }
.stepper__step:nth-child(3) { --step: var(--blue); }
.stepper__step:nth-child(4) { --step: var(--lblue); }

.stepper__ring {
  display: block;
  width: 20px;
  height: 20px;
  overflow: visible;
}

.stepper__ring circle {
  fill: none;
  stroke: var(--step);
  stroke-width: 4.5;
}

/* Where you are is filled in; the rest are the outline they always were. */
.stepper__step[aria-current] .stepper__ring circle { fill: var(--step); }

/* A ring is 20px, which a mouse can hit and a thumb cannot. Where the
   pointer is coarse the steps take padding until they clear 44px; where it is
   not, the stepper stays the compact 35px row it was drawn as. */
@media (pointer: coarse) {
  .stepper { gap: 0.4rem; }
  .stepper__step { padding: 0.5rem 0.85rem; }
}

/* 0.45 read as dimmed and measured 3.58:1, which is not a colour a label
   this small can afford. The step you are on takes full paper instead, so the
   difference between the two is kept without the other three going quiet. */
.stepper__label {
  font-weight: 400;
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  color: rgba(242,239,233,0.62);
}

.stepper__step[aria-current] .stepper__label { color: var(--paper); }
.stepper__step:hover .stepper__label { color: var(--yellow); }

/* --- title and body ------------------------------------------------------ */

.doc .doc__title-step {
  font-size: 0.42em;
  font-weight: 400;
  letter-spacing: 0.16em;
  color: var(--step-colour);
  white-space: nowrap;
}

.sheet { margin-top: clamp(1rem, 3vw, 1.4rem); }

.sheet:first-of-type { margin-top: clamp(2rem, 5vw, 2.8rem); }

/* A panel opens with its heading, which needs no room above it in here. */
.sheet > :first-child { margin-top: 0; }

/* The dash is the marker, so the list stays a list. */
.dash-list {
  margin: 0.9rem 0 0;
  padding: 0;
  list-style: none;
}

.dash-list li {
  position: relative;
  margin-top: 0.55rem;
  padding-left: 1.5em;
  font-weight: 300;
  font-size: clamp(1rem, 2.5vw, 1.05rem);
  letter-spacing: 0.02em;
  line-height: 1.7;
  color: rgba(242,239,233,0.82);
}

.dash-list li::before {
  content: '—';
  position: absolute;
  left: 0;
  color: rgba(169,212,236,0.85);
}

/* --- the way on ---------------------------------------------------------- */

.doc .doc__next {
  margin: clamp(1.6rem, 4vw, 2.2rem) 0 0;
  text-align: center;
  font-weight: 400;
  font-size: clamp(1rem, 2.6vw, 1.15rem);
  letter-spacing: 0.04em;
  line-height: 1.5;
  color: rgba(169,212,236,0.85);
}

.doc .doc__next + .doc__next { margin-top: 0.7rem; }

/* --- Qué hacemos: rows that open ----------------------------------------- */

.row + .row { border-top: 1px solid rgba(255,255,255,0.08); }
.row:first-of-type { margin-top: 0.6rem; }

/* Brand order down the rows: the cycle the bullet rings and the stepper run. */
.row:nth-of-type(1) { --row-ring: var(--yellow); }
.row:nth-of-type(2) { --row-ring: var(--amber); }
.row:nth-of-type(3) { --row-ring: var(--blue); }
.row:nth-of-type(4) { --row-ring: var(--lblue); }

/* A three-row section starts at amber, as a three-item list does in the
   scenes — so a page with three services colours itself correctly. */
.row:first-of-type:nth-last-of-type(3) { --row-ring: var(--amber); }
.row:first-of-type:nth-last-of-type(3) ~ .row:nth-of-type(2) { --row-ring: var(--blue); }
.row:first-of-type:nth-last-of-type(3) ~ .row:nth-of-type(3) { --row-ring: var(--lblue); }

.row__head {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.85rem 0;
  cursor: pointer;
  list-style: none;
}

/* The browser's own triangle, gone in both spellings. */
.row__head::-webkit-details-marker { display: none; }
.row__head::marker { content: ''; }

/* The hover lift is painted by a layer that bleeds past the text, so the row
   highlights without the ring leaving the heading's left edge. */
.row__head::after {
  content: '';
  position: absolute;
  inset: 0 -0.7rem;
  z-index: -1;
  border-radius: 0.5rem;
  background: transparent;
  transition: background 180ms ease;
  pointer-events: none;
}

.row__ring {
  flex: none;
  width: 18px;
  height: 18px;
  overflow: visible;
}

.row__ring circle {
  fill: none;
  stroke: var(--row-ring);
  stroke-width: 4.5;
  opacity: 0.85;
  transition: opacity 180ms ease;
}

.row__name {
  font-weight: 500;
  font-size: clamp(1rem, 2.6vw, 1.08rem);
  letter-spacing: 0.02em;
  line-height: 1.35;
  color: var(--paper);
}

/* Same stroke weight as the rings, so the two read as one family. */
.row__chevron {
  flex: none;
  margin-left: auto;
  width: 16px;
  height: 16px;
  fill: none;
  stroke: rgba(242,239,233,0.5);
  stroke-width: 4.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 180ms ease, stroke 180ms ease;
}

.row[open] .row__chevron { transform: rotate(180deg); }

/* Nothing moves: the fill and the two strokes are all that change. */
@media (hover: hover) and (pointer: fine) {
  .row__head:hover::after { background: rgba(255,255,255,0.045); }
  .row__head:hover .row__ring circle { opacity: 1; }
  .row__head:hover .row__chevron { stroke: rgba(242,239,233,0.82); }
}

/* A thumb needs the whole row, not the words in it. */
@media (pointer: coarse) {
  .row__head { min-height: 44px; }
}

.row__body {
  padding: 0 0 1.1rem calc(18px + 0.85rem);
  animation: row-open 180ms ease both;
}

.doc .row__body p { margin-top: 0; }

/* Some rows hold two paragraphs; only the first sits tight to the label. */
.doc .row__body p + p { margin-top: 0.9rem; }

@keyframes row-open {
  from { opacity: 0; transform: translateY(-2px); }
  to   { opacity: 1; transform: none; }
}

/* --- Qué te llevás: the rings, larger, with more air --------------------- */

.ring-list {
  margin: 1.2rem 0 0;
  padding: 0;
  list-style: none;
}

.ring-list li {
  position: relative;
  margin-top: 1.1rem;
  padding-left: 2em;
  font-weight: 300;
  font-size: clamp(1.1rem, 2.9vw, 1.2rem);
  letter-spacing: 0.02em;
  line-height: 1.6;
  color: rgba(242,239,233,0.9);
}

.ring-list li:first-child { margin-top: 0; }

/* The bullet marker's own proportions — a thick stroke on a small circle —
   drawn with a border rather than an SVG, since there is nothing else to it. */
.ring-list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.4em;
  width: 0.72em;
  height: 0.72em;
  border: 0.2em solid var(--mark);
  border-radius: 50%;
}

.ring-list li:nth-child(1) { --mark: var(--yellow); }
.ring-list li:nth-child(2) { --mark: var(--amber); }
.ring-list li:nth-child(3) { --mark: var(--blue); }
.ring-list li:nth-child(4) { --mark: var(--lblue); }

.ring-list li:first-child:nth-last-child(3) { --mark: var(--amber); }
.ring-list li:first-child:nth-last-child(3) ~ li:nth-child(2) { --mark: var(--blue); }
.ring-list li:first-child:nth-last-child(3) ~ li:nth-child(3) { --mark: var(--lblue); }

/* Opening and closing is a change of state, not a performance. */
@media (prefers-reduced-motion: reduce) {
  .row__head::after,
  .row__ring circle,
  .row__chevron { transition: none; }

  .row__body { animation: none; }
}
