@font-face {
  font-family: 'TWK Everett';
  src: url('../public/assets/brand/fonts/TWKEverett-Regular.woff2') format('woff2');
  font-style: normal;
  font-weight: 400;
  font-display: block;
}
@font-face {
  font-family: 'Inter 28pt';
  src: url('../public/assets/brand/fonts/Inter28pt-Regular.woff2') format('woff2');
  font-style: normal;
  font-weight: 400;
  font-display: block;
}
@font-face {
  font-family: 'Inter 28pt';
  src: url('../public/assets/brand/fonts/Inter28pt-SemiBold.woff') format('woff');
  font-style: normal;
  font-weight: 600;
  font-display: block;
}
:root {
  /* Brand and optical material controls */
  --td7-bg: #f4f0e8; --td7-text: #022b32;
  /* Central light palette — pixel-sampled from public/assets/brand/graphics/green_ball.webp.
     No blue in the source artwork; --light-blue was the biggest color-match bug and is gone. */
  --light-teal: #06565c; --light-mid: #2f8f7c; --light-mint: #bdfbc0;
  --field-intensity: .9; --field-blur: 50px; --lavender-intensity: .3;
  --teal-duration: 10s; --mint-duration: 8s; --ambient-duration: 16s;
  --orbit-opacity: .62; --orbit-thickness: 1.4px;
  --node-diameter: 17px; --pill-height: 36px; --interaction-speed: 360ms;
  --glass-blur: 38px; --glass-transparency: .62; --td7-hairline: rgb(2 43 50 / 15%);
  /* Verified against the live thedigital7.com stylesheet (hex frequency count), not invented. */
  --brand-mint: #c1fcc0; --brand-lavender-pale: #dbceff; --brand-lavender-deep: #9c96d7;
  --brand-blue-text: #4a7a94; --lang-active-accent: #c9b4ff; --brand-purple-deep: #7a6fc4;
  --td7-font-primary: 'Inter 28pt'; --td7-font-heading: 'TWK Everett';
  --td7-ease: cubic-bezier(.16, 1, .3, 1); --td7-card-width: 860px;
  --td7-shadow: 0 50px 100px -35px rgb(2 43 50 / 35%), 0 14px 34px -8px rgb(2 43 50 / 10%), inset 0 0 46px rgb(156 150 215 / 8%), inset 0 1px 0 rgb(255 255 255 / 70%), inset 0 -1px 0 rgb(2 43 50 / 4%);
}
* { box-sizing: border-box; }
html { background: var(--td7-bg); color: var(--td7-text); font-synthesis: none; }
body { margin: 0; font-family: var(--td7-font-primary); font-weight: 400; overflow: hidden; }
button, a { -webkit-tap-highlight-color: transparent; }
button { font: inherit; color: inherit; cursor: pointer; }
button, a, h1, p { margin: 0; }
a { color: inherit; }
[hidden] { display: none !important; }
/* dvh, not svh: svh is the height with the mobile URL bar shown, so once the
   bar hides an empty strip appeared under the page. */
.experience { position: relative; height: 100vh; height: 100dvh; overflow: hidden; overflow: clip; }
/* Restrained illumination extending across the whole cream canvas, well beyond
   the orbit — separate from the central light-stack. Screen-blended, so cream
   stays dominant; opacity is intentionally low (--lavender-intensity). */
.wave-lavender { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: visible; animation: waveDrift 30s ease-in-out infinite alternate; mix-blend-mode: screen; }
/* z-index raised above the project card (10) and about panel (11) — the
   contact CTA must stay reachable while either is open, per review. */
.site-header { position: absolute; inset: max(28px, env(safe-area-inset-top)) 36px auto; z-index: 20; display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.brand-mark { display: block; --mark-width: 216px; width: var(--mark-width); height: calc(var(--mark-width) * 87.1131 / 525); overflow: hidden; user-select: none; flex-shrink: 0; }
.brand-mark svg { display: block; width: 100%; height: 100%; }
.header-actions { display: flex; align-items: center; gap: 18px; }
.languages { display: flex; align-items: center; gap: 7px; font-size: 14px; margin-right: 12px; }
/* display: flex + centering — without it, min-height: 44px (kept for the touch target) stretches the box taller than its text needs, and the extra space isn't distributed evenly by default, so ES/EN sat slightly off-center from the "|" separator, which IS centered via .languages' own flex row. */
.languages button { position: relative; display: inline-flex; align-items: center; justify-content: center; border: 0; background: transparent; padding: 0 6px; opacity: .5; min-height: 44px; line-height: 1; }
/* Underline drawn as a pseudo-element so the active button keeps exactly the
   same box as the inactive one — a border + different padding made ES and EN
   sit at different heights. text-shadow fakes the bold so the width doesn't
   jump either. */
.languages button::after { content: ''; position: absolute; left: 6px; right: 6px; top: calc(50% + .8em); height: 2.5px; border-radius: 2px; background: var(--lang-active-accent); opacity: 0; }
.languages button[aria-pressed='true'] { opacity: 1; text-shadow: .35px 0 0 currentColor, -.35px 0 0 currentColor; }
.languages button[aria-pressed='true']::after { opacity: 1; }
.languages span { line-height: 1; }
.site-link { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 14px 28px; border: 1px solid rgb(2 43 50 / 65%); border-radius: 50px; text-decoration: none; font-size: 14px; font-weight: 600; transition: background 300ms ease, border-color 300ms ease; }
.site-link:hover { background: rgb(156 150 215 / 22%); border-color: var(--td7-text); }
.site-link:focus-visible { outline: 2px solid var(--brand-lavender-pale); outline-offset: 3px; }
/* Primary conversion CTA — filled, distinct from the secondary "visit site" outline link. */
.site-link.is-primary { background: var(--brand-mint); border-color: transparent; }
.site-link.is-primary:hover { background: #aef2ad; }
.exploration-cue { position: absolute; top: min(20svh, 200px); left: 40px; z-index: 6; max-width: 640px; pointer-events: none; transition: opacity 200ms ease; }
.exploration-cue.is-dimmed { opacity: 0; }
.cue-eyebrow { font-family: var(--td7-font-heading); font-size: 43px; font-weight: 400; letter-spacing: -.01em; line-height: 1.2; margin: 0 0 10px; display: flex; align-items: flex-end; gap: .28em; flex-wrap: nowrap; white-space: nowrap; }
/* flex-end + equal 1.2em boxes keep the rotating word on the lead's baseline —
   `baseline` alignment used the overflow:hidden box's bottom edge and lifted it. */
/* Same mechanic as thedigital7.com's own hero rotator: a static lead phrase
   with one word cycling vertically through a stack. Pure CSS — each word
   plays the identical keyframe, offset by a negative animation-delay so
   exactly one is centered at any moment while the others wait off-screen. */
/* All words share one grid cell, so the rotator is always as wide as the longest word. */
.cue-rotator { position: relative; flex-shrink: 0; height: 1.2em; overflow: hidden; display: inline-grid; min-width: 6.6em; }
.cue-word { grid-area: 1 / 1; white-space: nowrap; opacity: 0; animation: cueWordCycle 9s linear infinite; }
/* Each word gets its delay (-3s × index) and the cycle for its word count from app.js. */
.cue-rotator[data-count="4"] .cue-word { animation-name: cueWordCycle4; }
.cue-rotator[data-count="5"] .cue-word { animation-name: cueWordCycle5; }
.cue-instruction { font-size: 15px; line-height: 1.55; opacity: .62; margin: 0; }
/* Given real presence with a decorative glow behind it, echoing the orbit's
   own light — rather than sitting bare on the cream. */
/* Bottom corners share one flex row (space-between + gap), so About and the
   counter can never overlap; on narrow screens the label shrinks/wraps first. */
.corner-bar { position: absolute; left: 40px; right: 40px; bottom: 36px; z-index: 6; display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; pointer-events: none; }
.corner-bar > * { pointer-events: auto; }
/* A open card/panel covers the stage: the corners would sit under or beside it. */
.experience:has(.project-card:not([hidden])) .corner-bar,
.experience:has(.about-panel:not([hidden])) .corner-bar { opacity: 0; visibility: hidden; }
.stat-counter { position: relative; flex: 0 1 auto; min-width: 0; display: flex; align-items: center; gap: 22px; }
.stat-counter::before { content: ''; position: absolute; right: -48px; bottom: -48px; width: 288px; height: 216px; pointer-events: none; filter: blur(48px); opacity: .4; background: radial-gradient(ellipse, var(--brand-lavender-deep) 0%, transparent 70%); mix-blend-mode: screen; z-index: -1; }
.stat-ring { position: relative; width: 130px; height: 130px; flex-shrink: 0; }
.stat-ring svg { display: block; width: 100%; height: 100%; }
/* The ring fill is driven by the same clientCount state as the number (see
   src/app.js) — not a decorative independent spin — so it fills at the exact
   pace of the count-up and reaches 100% exactly when the count reaches
   target. Rotated -90deg so the fill starts at 12 o'clock, at the dot. */
.stat-ring-arc { transform: rotate(-90deg); transform-origin: 54px 54px; transition: stroke-dasharray 80ms linear; }
.stat-ring-dot { transition: opacity 220ms ease; }
.stat-number-wrap { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
.stat-number { position: relative; display: block; font-family: var(--td7-font-heading); font-size: 41px; font-weight: 400; letter-spacing: -.02em; line-height: 1; font-variant-numeric: tabular-nums; background: linear-gradient(120deg, var(--brand-purple-deep) 0%, var(--brand-lavender-deep) 55%, var(--lang-active-accent) 100%); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
/* Label + a quiet link to all TD7 cases underneath; the counter stays the focus. */
.stat-text { display: flex; flex-direction: column; align-items: flex-start; gap: 20px; }
.stat-all { position: relative; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: inherit; opacity: .5; text-decoration: none; border-bottom: 1px solid rgb(2 43 50 / 25%); padding-bottom: 2px; white-space: nowrap; transition: opacity 180ms ease; }
.stat-all:hover, .stat-all:focus-visible { opacity: .9; }
.stat-label { position: relative; font-size: 14px; letter-spacing: .09em; text-transform: uppercase; opacity: .65; font-weight: 600; max-width: 9ch; line-height: 1.35; text-align: left; }
.orbital-system { position: absolute; top: 56%; left: 50%; z-index: 1; width: min(94vw, 88svh, 1040px); aspect-ratio: 1; transform: translate(-50%, -50%); isolation: isolate; --light-x: 0px; --light-y: 0px; }
/* The mark contains unchanged paths from the supplied standalone TD7 SVG. */
.central-mark { position: absolute; width: 20%; height: auto; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 5; pointer-events: none; }
/* Independent light fields, each a core+halo pair so they read as luminosity
   rather than a flat tinted blob. Masked as a group (not per-layer border-radius)
   so the falloff is a true circle: a bare radial-gradient mask defaults to
   farthest-corner sizing, which fades at the corners but stays opaque at the
   middle of each edge — visible as a faint square inside the glow. */
.light-stack {
  position: absolute; inset: 0; pointer-events: none;
  -webkit-mask-image: radial-gradient(circle closest-side at 50% 50%, black 45%, transparent 100%);
  mask-image: radial-gradient(circle closest-side at 50% 50%, black 45%, transparent 100%);
}
.field { position: absolute; pointer-events: none; }
/* Each layer carries its own inset (not a uniform wrapper inset) so the three
   reach different distances past the rings — this is what lets the ambient
   layer bleed well beyond the outer orbit while the core stays tight. */
.field-teal {
  inset: -6%; z-index: 1; filter: blur(calc(var(--field-blur) * .5)); opacity: var(--field-intensity);
  background:
    radial-gradient(22% 26% at 32% 46%, var(--light-teal) 0%, var(--light-teal) 30%, transparent 72%),
    radial-gradient(48% 54% at 34% 48%, var(--light-mid) 0%, transparent 80%);
  animation: driftDeep var(--teal-duration) ease-in-out infinite alternate;
}
.field-mint {
  inset: -10%; z-index: 2; mix-blend-mode: screen; filter: blur(calc(var(--field-blur) * .55)); opacity: calc(var(--field-intensity) * 1.05);
  background:
    radial-gradient(26% 30% at 64% 44%, var(--light-mint) 0%, var(--light-mint) 32%, transparent 74%),
    radial-gradient(54% 60% at 62% 48%, var(--light-mid) 0%, transparent 82%);
  animation: driftBright var(--mint-duration) ease-in-out infinite alternate;
}
.field-ambient {
  inset: -34%; z-index: 0; filter: blur(calc(var(--field-blur) * 2.1)); opacity: calc(var(--field-intensity) * .22);
  background: radial-gradient(60% 60% at 48% 50%, var(--light-mid) 0%, transparent 70%);
  animation: driftAmbient var(--ambient-duration) ease-in-out infinite alternate;
}
.orbital-system::after { content: ''; position: absolute; inset: 0; pointer-events: none; opacity: 0; border-radius: 50%; filter: blur(55px); background: radial-gradient(ellipse at 50% 50%, rgb(193 252 192 / 13%), transparent 65%); transform: translate(var(--light-x), var(--light-y)); transition: transform 1.8s ease, opacity 1.8s ease; z-index: -1; }
.orbital-system.is-responsive::after { opacity: 1; }
/* Screen blend only ever lightens, so the ring stays visible over the dark
   side of the light field and fades naturally into brighter areas, rather
   than the multiply-like darkening a normal/overlay blend would cause. */
.orbit { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); aspect-ratio: 1; border: var(--orbit-thickness) solid rgb(255 255 255 / 88%); mix-blend-mode: screen; border-radius: 50%; opacity: var(--orbit-opacity); pointer-events: none; z-index: 3; }
.orbit-inner { width: 40%; } .orbit-outer { width: 80%; }
.project-nodes { position: absolute; inset: 0; z-index: 7; pointer-events: none; }
.project-node { pointer-events: auto; }
.project-node { position: absolute; left: 50%; top: 50%; width: 44px; height: 44px; border: 0; padding: 0; border-radius: 50%; background: transparent; display: grid; place-items: center; outline: none; touch-action: manipulation; will-change: transform; overflow: visible; z-index: 3; transition: opacity 300ms ease; }
.project-node.is-pill, .project-node:focus-visible, .project-node[aria-expanded='true'] { z-index: 4; }
/* Rest state: a soft blurred glow, not a hard-edged dot or hollow ring — both
   were tried and rejected in design review. The small opaque white core (the
   0%/16% stops) matters: without it the orbit ring line visibly shows through
   the node sitting on top of it. */
.node-pill {
  position:absolute; left:50%; top:50%; display:flex; align-items:center; justify-content:center;
  height:var(--node-diameter); width:var(--node-diameter); padding:0; overflow:hidden; border-radius:999px;
  transform:translate(-50%,-50%); mix-blend-mode:screen; filter:blur(2px);
  background:radial-gradient(circle,#ffffff 0%,#ffffff 16%,rgb(255 255 255 / 40%) 34%,var(--light-mint) 54%,transparent 78%);
  transition:width var(--interaction-speed) var(--td7-ease), height var(--interaction-speed) var(--td7-ease), background 280ms ease, filter 280ms ease, box-shadow 280ms ease, border-color 280ms ease;
}
.node-label { font-family:var(--td7-font-heading); font-size:12px; line-height:1.2; white-space:nowrap; opacity:0; max-width:0; overflow:hidden; text-overflow:ellipsis; flex-shrink:0; transition:opacity 180ms ease, max-width var(--interaction-speed) var(--td7-ease); }
.project-node.is-pill .node-pill, .project-node:focus-visible .node-pill {
  width:var(--pill-width); height:var(--pill-height); mix-blend-mode:normal; filter:none;
  background:linear-gradient(150deg,rgb(255 255 255 / 80%),rgb(244 240 232 / 60%));
  border:1px solid rgb(255 255 255 / 65%);
  box-shadow:inset 0 1px 0 rgb(255 255 255 / 75%), 0 10px 24px -6px rgb(2 43 50 / 22%);
  -webkit-backdrop-filter:blur(12px); backdrop-filter:blur(12px);
}
.project-node.is-pill .node-label, .project-node:focus-visible .node-label { opacity:1; max-width:150px; transition-delay:90ms; }
.project-node[aria-expanded='true'] .node-pill { box-shadow:0 0 0 4px rgb(244 240 232 / 8%), inset 0 1px 0 rgb(255 255 255 / 75%); }
.project-node:focus-visible { outline:none; }
.project-node:focus-visible .node-pill { outline:1px solid var(--td7-text); outline-offset:3px; }
.has-active .project-node:not([aria-expanded='true']) { opacity: .52; }
.has-active .project-node.is-pill, .has-active .project-node:focus-visible { opacity: 1; }

/* About us opens only from the bottom-left pill: the old invisible hover target
   over the TD7 mark got in the way of navigating the inner orbit. */
/* Always-visible second entry point, bottom-left — matching the stat-counter's
   visual weight on the opposite corner. Its own soft teal glow (vs. the
   stat-counter's purple) so the two corners read as a matched pair, not twins. */
.about-cta { position: relative; flex: 0 0 auto; white-space: nowrap; display: inline-flex; align-items: center; gap: 12px; background: rgb(244 240 232 / 55%); -webkit-backdrop-filter: blur(16px) saturate(140%); backdrop-filter: blur(16px) saturate(140%); border: 1px solid rgb(255 255 255 / 55%); border-radius: 999px; padding: 14px 24px 14px 18px; cursor: pointer; font-family: var(--td7-font-primary); box-shadow: 0 12px 28px -10px rgb(2 43 50 / 22%); transition: background 220ms ease, border-color 220ms ease; }
.about-cta::before { content: ''; position: absolute; left: -30px; bottom: -30px; width: 200px; height: 150px; pointer-events: none; filter: blur(40px); opacity: .35; background: radial-gradient(ellipse, var(--light-mid) 0%, transparent 70%); mix-blend-mode: screen; z-index: -1; }
.about-cta:hover { background: rgb(193 252 192 / 40%); border-color: var(--td7-text); }
/* Previous pass (many keyframe stops, wide opacity/scale swings, 2.6s) read
   as jittery flicker, not a light — this is a slow two-stage glow instead: a
   soft box-shadow halo breathing in and out, narrow opacity range, no scale
   jump. Calmer, and it actually looks like it's emitting light. */
/* A small purple light that blinks: bright core + soft halo switching on and
   off (quick fade, not a slow breathe), so it reads as a live indicator. */
.about-cta-dot { position: relative; width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; background: radial-gradient(circle, #f1ecff 0%, #b9a8ff 38%, #7a6fc4 100%); box-shadow: 0 0 6px 2px rgb(156 150 215 / 75%), 0 0 16px 5px rgb(122 111 196 / 40%); animation: about-dot-blink 2.2s ease-in-out infinite; }
@keyframes about-dot-blink {
  0%, 18%, 100% { opacity: 1; box-shadow: 0 0 6px 2px rgb(156 150 215 / 80%), 0 0 16px 5px rgb(122 111 196 / 45%); }
  30%, 42% { opacity: .18; box-shadow: 0 0 0 0 rgb(156 150 215 / 0%), 0 0 0 0 rgb(122 111 196 / 0%); }
  54% { opacity: 1; box-shadow: 0 0 7px 2px rgb(156 150 215 / 85%), 0 0 18px 6px rgb(122 111 196 / 50%); }
}
.about-cta-label { font-size: 13px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--td7-text); opacity: .85; transition: opacity 200ms ease; }
.about-cta:hover .about-cta-label { opacity: 1; }
/* Same cut-corner bevel as .project-card now, per explicit review direction —
   an earlier pass deliberately used plain rounded corners so About wouldn't
   read as "another project," but the user wants it matching the card shape,
   so that distinction is gone. Same footprint as .project-card too. */
.about-panel { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 11; width: var(--td7-card-width); max-width: calc(100vw - 32px); height: min(720px, calc(100svh - 180px)); max-height: calc(100svh - 100px); clip-path: polygon(36px 0, 100% 0, 100% calc(100% - 36px), calc(100% - 36px) 100%, 0 100%, 0 36px); overflow: hidden; display: flex; flex-direction: column; background: linear-gradient(160deg, rgb(255 255 255 / 32%) 0%, rgb(255 255 255 / 6%) 40%, rgb(156 150 215 / 16%) 100%), radial-gradient(90% 65% at 100% 0%, rgb(189 251 192 / 9%), transparent 55%), radial-gradient(100% 80% at 0% 100%, rgb(156 150 215 / 34%), transparent 58%), rgb(244 240 232 / 60%); -webkit-backdrop-filter: blur(32px) saturate(145%); backdrop-filter: blur(32px) saturate(145%); border: 1px solid rgb(255 255 255 / 60%); box-shadow: var(--td7-shadow); }
.about-panel.is-revealing { animation: card-enter-centered 260ms var(--td7-ease) both; }
.about-panel::before { content: ''; position: absolute; inset: -20% -50%; z-index: 1; pointer-events: none; background: linear-gradient(115deg, transparent 40%, rgb(255 255 255 / 26%) 48%, rgb(255 255 255 / 8%) 53%, transparent 62%); transform: rotate(-2deg); }
.about-panel-inner { position: relative; z-index: 2; width: 100%; flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: 50px 46px 28px; box-sizing: border-box; scrollbar-width: thin; scrollbar-color: #022b3226 transparent; }
.about-panel-inner::-webkit-scrollbar { width: 6px; }
.about-panel-inner::-webkit-scrollbar-thumb { background: rgb(2 43 50 / 18%); border-radius: 3px; }
.about-kicker { font-size: 12px; letter-spacing: .09em; text-transform: uppercase; opacity: .55; margin: 0 0 14px; }
.about-title { font-family: var(--td7-font-heading); font-size: 34px; line-height: 1.14; font-weight: 400; letter-spacing: -.02em; margin: 0 0 24px; max-width: 26ch; color: var(--brand-lavender-deep); }
/* Oversized opening mark instead of straight quote-marks — editorial,
   "pulled from a manifesto" feel rather than a boxed testimonial. */
.about-mission { position: relative; font-family: var(--td7-font-heading); font-weight: 400; font-size: 19px; line-height: 1.56; letter-spacing: -.005em; margin: 0 0 40px; max-width: 56ch; opacity: .9; padding-left: 34px; }
.about-mission::before { content: '"'; position: absolute; left: -6px; top: -22px; font-family: Georgia, 'Times New Roman', serif; font-size: 76px; line-height: 1; color: var(--brand-lavender-deep); opacity: .45; }
/* Real team photos (Jorge, Susana, Tania — sourced from thedigital7.com's own
   team section), not stock/placeholder imagery. Only three, and they fit one
   row comfortably at this panel width, so a static row reads cleaner than
   forcing scroll-snap carousel mechanics onto three items. */
.about-team { display: flex; gap: 20px; margin: 0 0 36px; }
.about-team-card { flex: 1 1 0; min-width: 0; }
/* The real source photos (from thedigital7.com) already have a diagonal
   bevel cutout baked in — a plain rounded-rectangle container let its own
   background color show through those transparent corners, reading as a
   mismatched border. Clipping the container to the same bevel shape instead
   means nothing renders in that corner at all (the panel's own background
   shows through cleanly), no more double-frame. */
.about-team-photo { width: 100%; aspect-ratio: 4 / 5; clip-path: polygon(14px 0, 100% 0, 100% calc(100% - 14px), calc(100% - 14px) 100%, 0 100%, 0 14px); background: rgb(2 43 50 / 6%); }
.about-team-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.about-team-photo.is-empty { display: flex; align-items: center; justify-content: center; border: 1px dashed rgb(2 43 50 / 25%); }
.about-team-photo-placeholder { font-size: 10px; letter-spacing: .05em; text-transform: uppercase; opacity: .4; }
.about-team-name { font-family: var(--td7-font-heading); font-size: 15px; font-weight: 400; margin: 12px 0 2px; color: var(--td7-text); }
.about-team-role { font-size: 12px; opacity: .62; margin: 0; }
.about-team-link { display: block; text-decoration: none; color: inherit; }
.about-team-link:hover .about-team-name { color: var(--brand-lavender-deep); }
.about-team-photo { position: relative; }
.about-team-name { display: flex; align-items: center; gap: 6px; }
.about-team-in { display: inline-grid; place-items: center; opacity: .55; transition: opacity 200ms ease; }
.about-team-link:hover .about-team-in { opacity: 1; }
.about-team-pill { position: absolute; left: 8px; bottom: 8px; padding: 4px 9px; border-radius: 999px; font-size: 10px; font-weight: 600; letter-spacing: .04em; color: var(--td7-text); border: 1px solid rgb(255 255 255 / 80%); background: linear-gradient(180deg, rgb(255 255 255 / 80%), rgb(255 255 255 / 58%)); -webkit-backdrop-filter: blur(12px) saturate(170%); backdrop-filter: blur(12px) saturate(170%); opacity: 0; transform: translateY(4px); transition: opacity 220ms ease, transform 220ms var(--td7-ease); }
.about-team-link:hover .about-team-pill, .about-team-link:focus-visible .about-team-pill { opacity: 1; transform: none; }
@media (hover: none) { .about-team-pill { opacity: 1; transform: none; } }
.about-team-in { font-family: var(--td7-font-primary); font-size: 10px; font-weight: 600; letter-spacing: .04em; opacity: .55; }
/* Matches the real about-us page's own treatment for these two headings
   (uppercase, TWK Everett) — verified live, not invented; sized up from
   their ~23px since this panel's context calls for more presence. Extra
   top margin on the second one only (.about-list + .about-section-title,
   i.e. whichever title starts a new section after a previous list) makes
   Values and Commitment read as two distinct sections, not one long list. */
.about-section-title { font-family: var(--td7-font-heading); font-weight: 400; font-size: 27px; text-transform: uppercase; letter-spacing: .01em; margin: 0 0 16px; color: var(--light-teal); }
.about-list + .about-section-title { margin-top: 48px; }
/* Plain divided list, not tinted cards — cards were tried and reverted in
   review as "too much." */
.about-list { margin: 0 0 30px; }
.about-item { padding: 26px 0; border-bottom: 1px solid rgb(2 43 50 / 7%); }
.about-item:first-child { padding-top: 0; }
.about-item:last-child { border-bottom: 0; padding-bottom: 0; }
.about-item-title { font-family: var(--td7-font-heading); font-weight: 400; font-size: 20px; letter-spacing: -.01em; margin: 0 0 8px; color: var(--brand-lavender-deep); }
.about-item-copy { font-size: 15.5px; line-height: 1.65; margin: 0; max-width: 58ch; opacity: .78; }
/* Calmer scale (review: "textos demasiado grandes, saturado"): one display
   size (the title), everything else small and airy; section headings become
   quiet eyebrow labels; Values/Commitment sit in two light columns. */
.about-panel-inner { padding: 40px 52px 24px; }
.about-kicker { font-size: 11px; letter-spacing: .12em; margin-bottom: 12px; }
.about-title { font-size: 28px; line-height: 1.18; margin-bottom: 18px; max-width: 24ch; }
.about-mission { font-family: var(--td7-font-primary); font-size: 15px; line-height: 1.7; letter-spacing: 0; max-width: 60ch; opacity: .78; padding-left: 0; margin-bottom: 36px; }
.about-mission::before { content: none; }
.about-team { gap: 18px; margin-bottom: 40px; }
.about-team-card { flex: 0 1 112px; }
.about-team-name { font-size: 13.5px; margin-top: 10px; }
.about-team-role { font-size: 11px; }
.about-section-title { font-family: var(--td7-font-primary); font-size: 11px; font-weight: 600; letter-spacing: .12em; opacity: .55; color: var(--td7-text); margin: 0 0 18px; }
.about-list + .about-section-title { margin-top: 40px; }
.about-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 36px; row-gap: 0; }
.about-item, .about-item:first-child, .about-item:last-child { padding: 16px 0 18px; border-bottom: 0; border-top: 1px solid rgb(2 43 50 / 8%); }
.about-item-title { font-size: 15.5px; margin-bottom: 6px; }
.about-item-copy { font-size: 13px; line-height: 1.6; opacity: .7; }
/* Tabs: glass segmented control, same pill material as the header/About CTA. */
.about-tabs { display: flex; width: fit-content; gap: 4px; padding: 4px; margin: 0 0 16px; border-radius: 999px; background: rgb(255 255 255 / 34%); border: 1px solid rgb(255 255 255 / 60%); box-shadow: inset 0 1px 0 rgb(255 255 255 / 70%); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.about-tabs::-webkit-scrollbar { display: none; }
.about-tabs [role='tab'] { flex: none; border: 0; background: transparent; border-radius: 999px; padding: 9px 16px; font-size: 12px; font-weight: 600; letter-spacing: .04em; color: var(--td7-text); opacity: .6; white-space: nowrap; transition: background 220ms ease, opacity 220ms ease, box-shadow 220ms ease; }
.about-tabs [role='tab']:hover { opacity: .9; }
.about-tabs [role='tab'][aria-selected='true'] { opacity: 1; background: rgb(255 255 255 / 78%); box-shadow: 0 4px 14px -6px rgb(2 43 50 / 25%), inset 0 1px 0 rgb(255 255 255 / 90%); }
.about-tabs [role='tab']:focus-visible { outline: 2px solid var(--brand-lavender-deep); outline-offset: 2px; }
.about-pane { animation: about-pane-in 220ms ease both; }
/* Fade only: a vertical slide read as a glitch when switching tabs. */
@keyframes about-pane-in { from { opacity: 0; } to { opacity: 1; } }
/* Tabs stay reachable while scrolling inside the panel. */
.about-tabs { position: sticky; top: 8px; z-index: 3; }
/* The tab names the section, so the in-pane headings are redundant. */
.about-pane .about-section-title { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.about-pane .about-list { margin: 0; }
/* Six commitments read as two rows of three; four values stay two by two. */
.about-pane .about-mission { margin: 0; font-size: 16px; }
/* Team row stays on top, above the tabs. Frame = TD7's characteristic
   diagonal cuts (top-left + bottom-right, same proportions as the source
   photos). The 758×1219 sources are framed at 3:4 on head and torso: the
   image is scaled so the crop x 240–720 / y 70–710 fills the frame, which
   keeps the baked transparent corners outside it. */
.about-team { gap: 22px; margin: 0 0 22px; }
.about-team-photo { max-width: 170px; }
.about-team-dots { display: none; }
/* Four equal columns across the full card width, so roles fit on one line. */
.about-team { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.about-team-card { min-width: 0; }
.about-team-photo { position: relative; overflow: hidden; aspect-ratio: 3 / 4; background: rgb(2 43 50 / 6%); clip-path: polygon(30% 0, 100% 0, 100% 80%, 70% 100%, 0 100%, 0 20%); }
/* Crop window x 180–758 / y 20–791 of the 758×1219 canvases (less zoom, faces centred). */
.about-team-photo img { position: absolute; width: 131.14%; height: auto; max-width: none; left: -31.14%; top: -2.59%; object-fit: initial; }
.about-team-photo.is-empty { border: 0; background: rgb(2 43 50 / 7%); }
.about-team-name { font-size: 12.5px; margin-top: 8px; }
.about-team-role { font-size: 10.5px; line-height: 1.35; }
/* Values/Commitment: numbered titles only; each opens its text in place. */
.about-pane .about-list { display: block; }
.about-pane .about-item, .about-pane .about-item:first-child, .about-pane .about-item:last-child { padding: 0; border-top: 1px solid rgb(2 43 50 / 8%); border-bottom: 0; }
.about-pane .about-item:last-child { border-bottom: 1px solid rgb(2 43 50 / 8%); }
.about-item-title { margin: 0; }
.about-item-toggle { display: flex; align-items: center; gap: 14px; width: 100%; padding: 11px 2px; border: 0; background: none; text-align: left; font: inherit; color: inherit; cursor: pointer; }
.about-item-num { font-family: var(--td7-font-primary); font-size: 10.5px; letter-spacing: .08em; opacity: .45; }
.about-item-label { flex: 1; font-family: var(--td7-font-heading); font-size: 16px; color: var(--td7-text); }
.about-item-sign { position: relative; width: 11px; height: 11px; opacity: .55; }
.about-item-sign::before, .about-item-sign::after { content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 1.2px; background: currentColor; transition: transform 220ms var(--td7-ease); }
.about-item-sign::after { transform: rotate(90deg); }
.about-item-toggle[aria-expanded='true'] .about-item-sign::after { transform: rotate(0deg); }
.about-item-toggle:hover .about-item-label { color: var(--brand-lavender-deep); }
.about-pane .about-item-copy { padding: 0 0 16px 38px; max-width: 60ch; }
/* Stable card height across tabs (no jump when switching). */
.about-panel { height: min(700px, calc(100svh - 120px)); }

/* Cut-corner bevel (top-left + bottom-right flat-cut) is the real card shape
   used on thedigital7.com's own "ADN" grid — confirmed by inspecting the live
   site, not invented — replacing a plain rounded rectangle. Two color tints
   (mint top-left, lavender bottom-right), not one flat green-tinted pane.
   Truly centered on the viewport (both axes via translate), not anchored to
   whichever node was clicked — that read as randomly placed and crowded the
   header CTAs. */
.project-card {
  position: fixed; top: 50%; left: 50%; z-index: 10; transform: translate(-50%, -50%);
  width: var(--td7-card-width); max-width: calc(100vw - 32px);
  height: min(720px, calc(100svh - 180px)); max-height: calc(100svh - 100px); display: flex; flex-direction: column; overflow: hidden;
  clip-path: polygon(36px 0, 100% 0, 100% calc(100% - 36px), calc(100% - 36px) 100%, 0 100%, 0 36px);
  border: 1px solid rgb(255 255 255 / 62%);
  background:
    linear-gradient(155deg, rgb(255 255 255 / 34%) 0%, rgb(255 255 255 / 7%) 38%, rgb(6 86 92 / 5%) 100%),
    radial-gradient(120% 90% at 12% 0%, rgb(189 251 192 / 13%), transparent 52%),
    linear-gradient(180deg, transparent 50%, rgb(248 245 239 / 60%) 100%), /* keeps the lower half light, not murky */
    radial-gradient(110% 85% at 100% 100%, rgb(156 150 215 / 11%), transparent 55%),
    rgb(244 240 232 / var(--glass-transparency));
  box-shadow: var(--td7-shadow);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(155%); backdrop-filter: blur(var(--glass-blur)) saturate(155%);
}
.project-card::before {
  content: ''; position: absolute; inset: -20% -60%; pointer-events: none; z-index: 1;
  background: linear-gradient(115deg, transparent 38%, rgb(255 255 255 / 30%) 47%, rgb(255 255 255 / 10%) 52%, transparent 62%);
  transform: rotate(-2deg);
}
/* flex: 1 1 auto + min-height: 0 (not height: 100%) is what actually lets a flex child scroll internally instead of either overflowing its container or refusing to shrink below its content size. The contact CTA used to be pinned on top of this (position: absolute, floating over whatever scrolled underneath it) — moved to its own non-scrolling footer row below instead, so it no longer overlaps content mid-scroll; ordinary bottom padding is enough now. */
.card-scroll { width: 100%; flex: 1 1 auto; min-height: 0; padding: 46px 44px 28px; overflow-y: auto; overflow-x: clip; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; scrollbar-width: thin; scrollbar-color: #022b3226 transparent; }
.project-card::after { content: ''; position: absolute; inset: auto 0 0; height: 44px; background: linear-gradient(transparent, #f4f0e8d9); pointer-events: none; opacity: 0; transition: opacity 200ms ease; }
.project-card.has-more::after { opacity: 1; }
.project-card.is-revealing { animation: card-enter-centered 260ms var(--td7-ease) both; }
/* Frosted-glass pills over the hero (close ✕, category, client logo): heavy
   blur + saturation so the photo glows through, a white wash strong enough
   to keep any logo legible on dark images, a bright top edge and a soft drop. */
.glass-pill, .close-control {
  border-radius: 999px; border: 1px solid rgb(255 255 255 / 78%);
  background: linear-gradient(180deg, rgb(255 255 255 / 78%), rgb(255 255 255 / 58%));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 95%), inset 0 -1px 0 rgb(255 255 255 / 25%), 0 10px 24px -12px rgb(0 22 28 / 45%);
  -webkit-backdrop-filter: blur(18px) saturate(185%); backdrop-filter: blur(18px) saturate(185%);
}
.close-control { position: absolute; top: 16px; right: 16px; z-index: 3; width: 38px; height: 38px; padding: 0; font-size: 14px; color: var(--td7-text); }
.close-control:hover { background: linear-gradient(180deg, rgb(255 255 255 / 92%), rgb(255 255 255 / 78%)); }
/* Hero: bleeds to the card edges (cancels .card-scroll padding) and follows its cut corner. */
.card-hero { position: relative; margin: -46px -44px 28px; aspect-ratio: 16 / 8.5; max-height: min(360px, 40svh); width: calc(100% + 88px); overflow: hidden; background: linear-gradient(135deg, rgb(189 251 192 / 45%), rgb(156 150 215 / 40%)); }
.card-hero[hidden] { display: none; }
.card-hero-media, .card-hero-media img, .card-hero-media video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.card-hero-media img { animation: image-reveal 320ms ease both; }
.hero-tag { position: absolute; top: 24px; left: 24px; max-width: calc(100% - 120px); padding: 7px 13px; font-size: 10px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--td7-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hero-logo { position: absolute; left: 24px; bottom: 20px; display: flex; align-items: center; padding: 8px 14px; }
.hero-logo img { display: block; object-fit: contain; }
.hero-tag[hidden], .hero-logo[hidden] { display: none; }
/* "Pieza destacada": one wide image/video between the challenge and the approach. */
.case-feature { margin: 6px 0 34px; }
.case-feature img, .case-feature video { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; clip-path: polygon(16px 0, 100% 0, 100% calc(100% - 16px), calc(100% - 16px) 100%, 0 100%, 0 16px); }
.case-feature figcaption { font-size: 12px; opacity: .6; margin-top: 8px; }
/* Shown when a visitor tries to scroll: the interaction is the points of light. */
.scroll-hint { position: fixed; left: 50%; bottom: 104px; z-index: 9; transform: translate(-50%, 8px); width: max-content; max-width: min(460px, calc(100vw - 32px)); padding: 12px 20px; border-radius: 22px; text-wrap: balance; text-align: center; font-size: 13px; line-height: 1.4; color: var(--td7-text); background: rgb(244 240 232 / 78%); border: 1px solid rgb(255 255 255 / 70%); box-shadow: 0 12px 28px -12px rgb(2 43 50 / 30%); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); opacity: 0; transition: opacity 300ms ease, transform 300ms var(--td7-ease); pointer-events: none; }
.scroll-hint.is-visible { opacity: 1; transform: translate(-50%, 0); }
/* A real footer row now — a sibling AFTER .card-scroll/.about-panel-inner in
   normal flex flow (flex-shrink: 0), not position: absolute floating on top
   of the scrolling content. It used to be pinned to the corner and stay on
   screen while content scrolled underneath it — which meant it permanently
   covered a few lines of text throughout the whole scroll on a panel this
   long (About), not just at the very end like on the shorter project card.
   A dedicated row gives it its own space with nothing ever hidden behind it. */
/* Own breathing room: a hairline gap above so scrolling text never sits against the pill, and closer to the card's bottom edge. */
.card-contact-cta { flex-shrink: 0; align-self: flex-start; margin: 18px 24px 14px; z-index: 4; display: inline-flex; align-items: center; gap: 6px; padding: 12px 20px; border-radius: 999px; background: rgb(244 240 232 / 82%); -webkit-backdrop-filter: blur(14px) saturate(140%); backdrop-filter: blur(14px) saturate(140%); border: 1px solid rgb(255 255 255 / 75%); box-shadow: inset 0 1px 0 rgb(255 255 255 / 85%), 0 8px 18px -12px rgb(2 43 50 / 16%); font-size: 12px; font-weight: 600; letter-spacing: .04em; color: var(--td7-text); text-decoration: none; transition: background 220ms ease, border-color 220ms ease; }
.card-contact-cta:hover { background: var(--brand-mint); border-color: transparent; }
/* Right padding keeps the logo clear of the close button (top-right, ~38–44px). */
.card-top-row { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin: 0 0 14px; padding-right: 44px; }
/* One line only; long category lists end in … instead of stacking beside the logo. */
.categories { flex: 1 1 auto; min-width: 0; font-size: 12px; letter-spacing: .09em; text-transform: uppercase; opacity: .6; margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Fixed height, not fixed width, object-fit: contain, so a wide horizontal
   logo and a tall/square one both center cleanly without distortion. */
.card-client-logo { flex-shrink: 0; height: 32px; max-width: 220px; display: flex; align-items: center; justify-content: center; }
.card-client-logo img { max-height: 100%; max-width: 100%; object-fit: contain; }
.card-client-logo .logo-mono { display: block; height: 28px; width: 90px; max-width: 160px; background: var(--td7-text); opacity: .85; -webkit-mask: var(--logo) center / contain no-repeat; mask: var(--logo) center / contain no-repeat; }
.card-client-logo .logo-wordmark { font-family: var(--td7-font-heading); font-size: 13px; letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; opacity: .72; padding: 7px 12px; border-radius: 999px; border: 1px solid rgb(2 43 50 / 16%); background: rgb(255 255 255 / 30%); }
.card-client-logo .logo-placeholder { font-size: 9px; letter-spacing: .05em; text-transform: uppercase; opacity: .35; border: 1px dashed rgb(2 43 50 / 25%); border-radius: 6px; padding: 10px 12px; }
/* Lavender is reserved for the card's primary title only — tried on section
   headings and the exploration cue in review and reverted both times. */
.project-name { font-family: var(--td7-font-heading); font-weight: 400; font-size: 42px; line-height: 1.06; letter-spacing: -.02em; color: var(--brand-lavender-deep); margin: 0 0 16px; overflow-wrap: anywhere; }
.card-labs { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 18px; }
/* Background carries the purple; text stays the real dark teal, since the
   verified brand purples are all light pastels with no legible dark variant. */
/* Border is a thin white highlight (the actual "glass edge" language used by
   .project-card/.about-panel/.card-contact-cta elsewhere), not a saturated
   purple outline — a colored border reads as a flat chip, not glass. Light
   backdrop-filter blur added for the same reason; still no box-shadow/sheen
   stacking on top, since that combination was reviewed as "too much" before. */
.card-lab-pill { font-size: 11px; font-weight: 500; letter-spacing: .03em; padding: 5px 12px; border-radius: 999px; background: linear-gradient(135deg, rgb(189 251 192 / 28%), rgb(156 150 215 / 32%)); border: 1px solid rgb(255 255 255 / 45%); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); color: var(--td7-text); white-space: nowrap; }
.project-subtitle { font-family: var(--td7-font-heading); font-size: 22px; line-height: 1.25; letter-spacing: -.01em; margin: -8px 0 16px; color: var(--td7-text); opacity: .85; }
.project-headline { font:400 20px/1.4 var(--td7-font-heading); letter-spacing:-.01em; margin:0 0 16px; max-width:34ch; }
.project-description { font-size: 15px; line-height: 1.66; opacity: .82; margin: 0 0 26px; max-width: 46ch; }
.project-media { position: relative; width: 100%; }
/* One gallery, at the top, replacing the old scattered hero + mid-copy media
   blocks — a real horizontally-scrollable/swipeable strip via native scroll-snap. */
.gallery-track {
  display: flex; width: 100%; overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; -ms-overflow-style: none; touch-action: pan-x pan-y; overscroll-behavior-x: contain;
  clip-path: polygon(16px 0, 100% 0, 100% calc(100% - 16px), calc(100% - 16px) 100%, 0 100%, 0 16px);
  border: 1px solid #022b320d;
}
.gallery-track::-webkit-scrollbar { display: none; }
.gallery-slide { position: relative; flex: 0 0 100%; aspect-ratio: 16 / 9; scroll-snap-align: start; scroll-snap-stop: always; display: grid; place-items: center; background: linear-gradient(135deg, #dddcd44d, #ffffff38); }
.gallery-slide img, .gallery-slide video { width: 100%; height: 100%; position: absolute; inset: 0; object-fit: contain; }
.gallery-slide img.reveal { animation: image-reveal 240ms ease; }
.image-placeholder { font-size: 10px; line-height: 1.4; opacity: .45; }
/* Video controls overlay ON the slide itself (bottom-right glass pill), not
   in the nav row below — sharing that row caused visible overlap in review. */
.gallery-controls { position: absolute; bottom: 10px; right: 10px; z-index: 1; display: flex; gap: 10px; padding: 6px 12px; border-radius: 20px; background: rgb(244 240 232 / 55%); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
/* Third brand accent (darkened from the live site's #9CC3D9 for text contrast),
   scoped to the gallery's own controls — a distinct role from mint and lavender. */
.media-toggle { border: 0; background: transparent; color: var(--brand-blue-text); opacity: .75; cursor: pointer; font-size: 9.5px; letter-spacing: .06em; padding: 0; }
.media-toggle:hover { opacity: 1; }
.media-nav { display: flex; align-items: center; justify-content: center; gap: 16px; margin-bottom: 30px; }
.media-nav button { width: 30px; height: 30px; padding: 0; border: 0; background: transparent; font-size: 17px; color: var(--brand-blue-text); opacity: .65; }
.media-nav button:hover { opacity: 1; }
.media-nav button:disabled { opacity: .3; cursor: default; }
#media-counter { font-size: 12px; font-variant-numeric: tabular-nums; opacity: .6; letter-spacing: .04em; color: var(--brand-blue-text); }
.project-metadata { display: grid; grid-template-columns: repeat(3, auto); align-items: start; gap: 34px; margin: 34px 0 30px; padding-top: 26px; border-top: 1px solid rgb(2 43 50 / 10%); }
.project-metadata dt { font-size: 10px; letter-spacing: .07em; text-transform: uppercase; opacity: .5; margin: 0 0 6px; }
.project-metadata dd { margin: 0; font-size: 13.5px; }
.project-links-label { font-size: 10px; letter-spacing: .07em; text-transform: uppercase; opacity: .5; margin: -8px 0 10px; }
.project-links { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 24px; }
.project-links a { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 600; letter-spacing: .03em; text-decoration: none; padding: 9px 14px; border-radius: 999px; border: 1px solid rgb(2 43 50 / 22%); background: rgb(255 255 255 / 35%); transition: background 200ms ease, border-color 200ms ease; }
.project-links a:hover { background: var(--brand-mint); border-color: transparent; }
.project-links .link-icon { flex: none; opacity: .8; }
.project-context { font-size: 15px; line-height: 1.7; margin: 26px 0; }
.card-footer { margin-top: 24px; }
.project-cta { display: inline-block; font-size: 13px; font-weight: 600; letter-spacing: .01em; text-decoration: none; padding: 0 0 10px; border-bottom: 1px solid rgb(2 43 50 / 22%); }
.project-cta:hover { border-color: var(--td7-text); }
.project-cta[aria-disabled='true'] { opacity: .4; cursor: default; }
a:focus-visible, button:focus-visible, .card-scroll:focus-visible { outline: 2px solid var(--td7-text); outline-offset: 3px; }
.project-cta:focus-visible { outline-color: var(--brand-lavender-pale); }
/* project-card's base transform is translate(-50%,-50%) for centering —
   a plain translateY endpoint here would wipe that out and the card would
   jump to the top-left corner. This variant preserves centering throughout. */
@keyframes card-enter-centered { from { opacity: 0; transform: translate(-50%, calc(-50% + 8px)); } to { opacity: 1; transform: translate(-50%, -50%); } }
/* Translate-only drift — scaling the whole field read as a pulsing/breathing
   blob in review. */
@keyframes driftDeep { 0% { transform: translate(-4%,2%); } 50% { transform: translate(3%,-4%); } 100% { transform: translate(-2%,-3%); } }
@keyframes driftBright { 0% { transform: translate(3%,-3%); } 50% { transform: translate(-4%,4%); } 100% { transform: translate(2%,3%); } }
@keyframes driftAmbient { from { transform: translate(-2%,2%); } to { transform: translate(3%,-2%); } }
@keyframes cueWordCycle {
  0% { opacity: 0; transform: translateY(45%); }
  4% { opacity: 1; transform: translateY(0); }
  29% { opacity: 1; transform: translateY(0); }
  33% { opacity: 0; transform: translateY(-45%); }
  100% { opacity: 0; transform: translateY(-45%); }
}
@keyframes cueWordCycle4 {
  0% { opacity: 0; transform: translateY(45%); }
  3% { opacity: 1; transform: translateY(0); }
  22% { opacity: 1; transform: translateY(0); }
  25% { opacity: 0; transform: translateY(-45%); }
  100% { opacity: 0; transform: translateY(-45%); }
}
@keyframes cueWordCycle5 {
  0% { opacity: 0; transform: translateY(45%); }
  2.4% { opacity: 1; transform: translateY(0); }
  17.6% { opacity: 1; transform: translateY(0); }
  20% { opacity: 0; transform: translateY(-45%); }
  100% { opacity: 0; transform: translateY(-45%); }
}
@keyframes image-reveal { from { opacity: .3; } to { opacity: 1; } }
@keyframes waveDrift {
  0% { transform: translate(-1.5%, 1%) rotate(-0.6deg); }
  33% { transform: translate(1.5%, -1.5%) rotate(0.5deg); }
  66% { transform: translate(-1%, 1.8%) rotate(-0.4deg); }
  100% { transform: translate(-1.5%, 1%) rotate(-0.6deg); }
}
@media (max-width: 700px) {
  /* Phones: one vertical flow — header, hero text, orbit (takes whatever
     height is left), bottom bar. Nothing is absolutely positioned against
     anything else, so no element can ever sit on top of another. */
  .experience { display: flex; flex-direction: column; gap: 30px; padding: max(18px, env(safe-area-inset-top)) 16px max(18px, env(safe-area-inset-bottom)); }
  /* Header in two clean rows: logo + language, then both CTAs side by side. */
  .site-header { position: relative; inset: auto; display: grid; grid-template-columns: 1fr 1fr; gap: 20px 8px; align-items: center; flex: none; }
  .header-actions { display: contents; }
  .brand-mark { --mark-width: 128px; }
  .languages { justify-self: end; }
  .site-link { width: 100%; padding: 8px 10px; font-size: 11px; min-height: 40px; white-space: nowrap; }
  .languages { gap: 2px; font-size: 12px; }
  .languages button { padding: 0 5px; min-height: 38px; }
  .languages button::after { left: 5px; right: 5px; }
  /* With a card open, the bottom corners and the in-card contact pill would
     read as duplicates behind/next to the header CTA on a small screen. */
  /* Denser glass on phones: the hero text and mark ghosting through read as duplicated content. */
  .project-card, .about-panel { background-color: rgb(244 240 232 / 93%); }
  .languages { margin-right: 0; }
  .exploration-cue { position: relative; top: auto; left: auto; max-width: none; flex: none; }
  .cue-eyebrow { font-size: 26px; flex-wrap: wrap; white-space: normal; row-gap: 0; }
  /* The orbit fills the remaining space and sizes itself to the smaller side
     (container query units), so it shrinks on short screens instead of
     overlapping the text above or the bar below. */
  .orbital-system { position: relative; top: auto; left: auto; transform: none; flex: 1 1 0; min-height: 160px; width: 100%; aspect-ratio: auto; container-type: size; }
  .orbital-system .light-stack { inset: auto; top: 50%; left: 50%; width: 100cqmin; height: 100cqmin; transform: translate(-50%, -50%); }
  .orbit-inner { width: 40cqmin; } .orbit-outer { width: 80cqmin; }
  .central-mark { width: 20cqmin; }
  /* Compact corner stat so it never collides with the About pill on the left. */
  .corner-bar { position: relative; left: auto; right: auto; bottom: auto; flex: none; gap: 10px; align-items: center; }
  .stat-counter { gap: 8px; }
  .stat-ring { width: 72px; height: 72px; }
  .stat-number { font-size: 23px; }
  .stat-label { font-size: 10.5px; max-width: 12ch; }
  .stat-counter::before { width: 180px; height: 140px; right: -30px; bottom: -30px; }
  .about-cta { padding: 10px 14px 10px 12px; gap: 8px; }
  .about-cta-label { font-size: 11px; letter-spacing: .05em; }
  .corner-bar { gap: 18px; }
  .stat-ring { width: 64px; height: 64px; }
  .stat-number { font-size: 20px; }
  .close-control { width: 44px; height: 44px; top: 12px; right: 12px; }
  .card-hero { margin: -34px -22px 22px; aspect-ratio: 4 / 3; max-height: 38svh; width: calc(100% + 44px); }
  /* Tag and logo share the same left edge. */
  .hero-tag { top: 24px; left: 24px; max-width: calc(100% - 100px); padding: 6px 11px; font-size: 9.5px; }
  .hero-logo { left: 24px; bottom: 20px; padding: 6px 11px; }
  .card-hero { margin-bottom: 30px; }
  /* No rubber-band at the top: it pulled the hero down and exposed the card's cut corner. */
  .card-scroll { overscroll-behavior: none; }
  .media-nav button { width: 44px; height: 44px; }
  .media-toggle { padding: 8px 4px; font-size: 10px; }
  .project-metadata { grid-template-columns: 1fr 1fr; gap: 18px 24px; }
  /* The wrapped two-row mobile header runs taller than desktop's, so this
     needs more reserved clearance than the desktop formula to keep the
     close button and top row from sitting under it (header stays on top
     by z-index, same as desktop, so it would otherwise cover them). */
  /* Header is a single row now (~64px), so the card can use more of the screen. */
  /* Card sits exactly between the two-row header (~122px) and a 16px bottom margin. */
  .project-card, .about-panel { top: calc(50% + 57px); height: calc(100dvh - 146px - env(safe-area-inset-top) - env(safe-area-inset-bottom)); max-height: none; }
  /* Bottom padding no longer needs to clear a pinned floating CTA — that
     moved to its own non-scrolling footer row, so this matches the desktop value now. */
  .card-scroll, .about-panel-inner { padding: 34px 22px 28px; }
  .project-name { font-size: 34px; margin-bottom: 24px; }
  .categories { font-size: 10.5px; letter-spacing: .07em; }
  .card-client-logo .logo-wordmark { font-size: 11px; padding: 6px 10px; }
  .card-top-row { gap: 12px; }
  .card-client-logo .logo-mono { height: 22px; max-width: 104px; }
  .project-headline { font-size: 19px; }
  .project-description { font-size: 14.5px; }
  .gallery-slide { aspect-ratio: 4 / 3; }
  .about-title { font-size: 22px; }
  .about-list { grid-template-columns: 1fr; }
  /* Phones: the team becomes a swipeable carousel with large portraits (one and
     a half visible, so it reads as scrollable); app.js auto-advances it. */
  .about-team { display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; margin: 0 -22px 22px; padding: 0 22px; scroll-padding-inline: 22px; overscroll-behavior-x: contain; }
  .about-team::-webkit-scrollbar { display: none; }
  .about-team-card { flex: 0 0 62%; scroll-snap-align: start; }
  .about-team-photo { max-width: none; }
  .about-team { margin-bottom: 12px; }
  .about-team-dots { display: flex; justify-content: center; gap: 8px; margin: 0 0 20px; }
  .about-team-dots button { width: 6px; height: 6px; min-height: 0; padding: 0; border: 0; border-radius: 999px; background: rgb(2 43 50 / 22%); transition: width 260ms var(--td7-ease), background 260ms ease; }
  .about-team-dots button.is-active { width: 18px; background: var(--brand-lavender-deep); }
  .about-team-name { font-size: 14px; line-height: 1.25; }
  .about-team-role { font-size: 11.5px; }
  .about-pane .about-mission { font-size: 14.5px; }
  .about-tabs { margin-bottom: 22px; }
  .about-tabs [role='tab'] { padding: 8px 12px; font-size: 11px; }
}
@media (max-width: 380px) { .stat-ring { width: 60px; height: 60px; } .stat-number { font-size: 19px; } .about-cta { padding: 10px 13px 10px 12px; gap: 8px; } .about-cta-label { font-size: 11.5px; letter-spacing: .04em; } .brand-mark { --mark-width: 112px; } .cue-eyebrow { font-size: 23px; } }
/* No breakpoint existed between 701px and full desktop — at typical laptop/
   preview widths in that range, the orbital system's min(94vw, 88svh, 1040px)
   sizing puts its left edge only ~30-150px from the viewport's left, directly
   under the 43px hero text (which starts at left: 40px and isn't capped by
   max-width, since white-space: nowrap ignores it) — the two were overlapping. */
@media (min-width: 701px) and (max-width: 1200px) {
  .cue-eyebrow { font-size: 30px; }
  .exploration-cue { max-width: 380px; }
  .orbital-system { width: min(78vw, 80svh, 1040px); }
}
@media (max-height: 580px) { .exploration-cue { top: 90px; max-width: 400px; } .cue-eyebrow { font-size: 28px; } .orbital-system { top: 62%; } .project-card, .about-panel { max-height: calc(100svh - 32px); } }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } }
@supports not (backdrop-filter: blur(1px)) { .project-card { background: rgb(244 240 232 / 94%); } .project-node.is-pill .node-pill { background: rgb(244 240 232 / 90%); } }

/* Case-study structure and neutral media placeholders. */
.case-section { margin:34px 0; }
/* Section titles as quiet eyebrows (lavender, letter-spaced, with a fine
   gradient rule) instead of big document-style headings; the first sentence
   of each block reads as a lead. */
.case-section h2.case-label { display:flex; align-items:center; gap:12px; font:600 11px/1 var(--td7-font-primary); letter-spacing:.14em; text-transform:uppercase; color:var(--brand-lavender-deep); margin:0 0 14px; }
.case-section h2.case-label::before { content:''; width:28px; height:1px; background:linear-gradient(90deg, var(--brand-lavender-deep), rgb(189 251 192 / 80%)); }
.case-section p.case-lead { font:400 19px/1.45 var(--td7-font-heading); letter-spacing:-.01em; opacity:.95; max-width:40ch; margin:0 0 12px; }
.case-section p { font-size:15px; line-height:1.72; max-width:62ch; opacity:.82; margin:0 0 10px; }
.case-list { margin:4px 0 14px; padding:0; list-style:none; max-width:62ch; }
.case-list li { position:relative; padding-left:18px; font-size:15px; line-height:1.6; opacity:.82; margin:0 0 6px; }
.case-list li::before { content:''; position:absolute; left:2px; top:.62em; width:5px; height:5px; border-radius:50%; background:var(--brand-lavender-deep); }
.media-caption { font-size:11px;line-height:1.5;opacity:.65;margin:10px 0; }
.content-error {position:fixed;bottom:25px;left:24px;right:24px;z-index:8;font-size:13px;line-height:1.6;text-align:center;}

/* Two columns inside the card: story on the left, facts + links on the right,
   starting level with the brand title and staying in view while scrolling.
   Plain text column — no box, no border. */
.card-body { display: grid; grid-template-columns: minmax(0, 1fr) 210px; gap: 44px; align-items: start; }
.card-aside { position: sticky; top: 0; padding: 20px 20px 16px; border-radius: 20px; background: linear-gradient(160deg, rgb(255 255 255 / 34%), rgb(255 255 255 / 12%)); box-shadow: inset 0 1px 0 rgb(255 255 255 / 55%); }
.card-aside .project-metadata { display: flex; flex-direction: column; gap: 16px; margin: 0 0 20px; padding: 0; border: 0; }
.card-aside .project-links-label { margin: 0 0 10px; }
.card-aside .project-links { flex-direction: column; align-items: flex-start; gap: 6px; margin: 0 0 18px; }
.card-aside .project-links a { padding: 7px 12px; font-size: 11.5px; border-color: transparent; background: rgb(255 255 255 / 45%); }
.card-aside .card-footer { margin-top: 4px; }
.card-aside .card-footer[hidden] { display: none; }
@media (max-width: 760px) {
  .card-body { grid-template-columns: 1fr; gap: 8px; }
  .card-aside { position: static; }
}

/* Previous / next project under the card: thin arrow + brand in faint text, «Proyectos» in between — no pills. */
/* One glass bar holds all three, with a soft mint→lavender glow and a slow sheen. */
.project-pager { position: fixed; left: 50%; bottom: 20px; z-index: 12; transform: translateX(-50%); display: flex; align-items: stretch; gap: 0; padding: 4px 6px; border-radius: 999px; overflow: hidden; isolation: isolate;
  border: 1px solid rgb(255 255 255 / 80%);
  background: linear-gradient(90deg, rgb(189 251 192 / 42%), rgb(255 255 255 / 58%) 50%, rgb(186 180 240 / 40%));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 95%), -14px 0 34px -4px rgb(189 251 192 / 85%), 14px 0 34px -4px rgb(156 150 215 / 70%), 0 0 60px 4px rgb(189 251 192 / 30%), 0 12px 26px -18px rgb(2 43 50 / 40%);
  animation: pager-glow 7s ease-in-out infinite;
  -webkit-backdrop-filter: blur(18px) saturate(180%); backdrop-filter: blur(18px) saturate(180%); }
.project-pager::before { content: ''; position: absolute; inset: 0; z-index: -1; background: linear-gradient(105deg, transparent 30%, rgb(255 255 255 / 70%) 48%, transparent 66%); background-size: 250% 100%; animation: pager-sheen 6s ease-in-out infinite; }
/* The glow drifts: mint and lavender slowly trade sides and breathe. */
@keyframes pager-glow {
  0%, 100% { box-shadow: inset 0 1px 0 rgb(255 255 255 / 95%), -14px 0 34px -4px rgb(189 251 192 / 85%), 14px 0 34px -4px rgb(156 150 215 / 70%), 0 0 60px 4px rgb(189 251 192 / 30%), 0 12px 26px -18px rgb(2 43 50 / 40%); }
  50% { box-shadow: inset 0 1px 0 rgb(255 255 255 / 95%), -14px 0 40px -2px rgb(156 150 215 / 75%), 14px 0 40px -2px rgb(189 251 192 / 90%), 0 0 70px 8px rgb(156 150 215 / 32%), 0 12px 26px -18px rgb(2 43 50 / 40%); }
}
@keyframes pager-sheen { 0%, 55% { background-position: 130% 0; } 100% { background-position: -130% 0; } }
.project-pager[hidden] { display: none; }
.pager-btn { display: inline-flex; align-items: center; gap: 4px; padding: 6px 4px; border: 0; background: none; color: var(--td7-text); opacity: .7; cursor: pointer; transition: opacity 200ms ease; }
.pager-btn.is-next { flex-direction: row-reverse; }
.pager-btn:hover, .pager-btn:focus-visible { opacity: 1; }
.pager-arrow { display: grid; place-items: center; width: 18px; height: 18px; transition: transform 200ms var(--td7-ease); }
.pager-arrow svg { width: 12px; height: 12px; }
.pager-btn.is-prev:hover .pager-arrow { transform: translateX(-2px); }
.pager-btn.is-next:hover .pager-arrow { transform: translateX(2px); }
.pager-text small { display: none; }
.pager-text strong { font-family: var(--td7-font-heading); font-weight: 400; font-size: 11.5px; letter-spacing: .01em; white-space: nowrap; max-width: 34vw; overflow: hidden; text-overflow: ellipsis; display: block; }
.pager-btn { justify-content: center; min-width: 120px; padding: 6px 14px; }
/* A light hairline splits the bar into two buttons. */
.pager-btn.is-next { position: relative; }
.pager-btn.is-next::before { content: ''; position: absolute; left: 0; top: 22%; bottom: 22%; width: 1px; background: linear-gradient(180deg, transparent, rgb(2 43 50 / 22%), transparent); }
@media (max-width: 700px) {
  /* Header is 8px taller (more air between its rows), so the card starts 8px lower. */
  .project-card { top: calc(50% + 31px); height: calc(100dvh - 198px - env(safe-area-inset-top) - env(safe-area-inset-bottom)); }
  .project-pager { bottom: calc(18px + env(safe-area-inset-bottom)); width: calc(100vw - 32px); }
  .pager-btn { flex: 1 1 0; min-width: 0; }
  .pager-text { min-width: 0; }
  .pager-text strong { max-width: none; }
}
/* About tabs: left on desktop, centred on phones. */
@media (max-width: 700px) { .about-tabs { margin-left: auto; margin-right: auto; } }

/* «Ver todos»: full text on desktop, short on phones (the long one was cut off). */
.stat-all-short { display: none; }
@media (max-width: 700px) {
  .stat-all-long { display: none; } .stat-all-short { display: inline; }
  .stat-text { gap: 10px; }
  .stat-all { font-size: 10px; letter-spacing: .08em; }
}
.pager-text { display: block; min-width: 0; overflow: hidden; }
