/* Motion layer. Loaded last; layout rules here are inert without motion, and the global reduced-motion rule still applies. */

/* ---------- Window-seat intro (only when intro-gate.js sets html[data-intro]) ---------- */
.intro{display:none}
html[data-intro] body{overflow:hidden}
html[data-intro] .intro{display:block;position:fixed;inset:0;z-index:1000;overflow:hidden;cursor:default;user-select:none;-webkit-user-select:none;
  --pw:clamp(150px,29vmin,226px);--ph:calc(var(--pw)*1.42);--lift:clamp(36px,8vh,80px);--trim:#fbfaf7;--accent:#244c66;--dot:#ad865a;
  animation:intro-failsafe .6s 9s forwards}
@keyframes intro-failsafe{to{opacity:0;visibility:hidden}}

.intro-wall{position:absolute;inset:0;background:var(--bg);background-image:radial-gradient(ellipse 70% 55% at 50% 38%,color-mix(in srgb,var(--panel) 70%,transparent),transparent 70%)}
.intro-porthole{position:absolute;left:50%;top:calc(50% - var(--lift));width:var(--pw);height:var(--ph);margin:calc(var(--ph)/-2) 0 0 calc(var(--pw)/-2);will-change:transform}
.intro-window{position:absolute;inset:0;border-radius:calc(var(--pw)*.46);overflow:hidden;background:#c2d9e7;isolation:isolate}
.intro-window:after{content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;box-shadow:inset 0 12px 18px -8px #0b1a2a4d,inset 0 -6px 12px -6px #ffffff80}
.intro-sky{position:absolute;inset:0;width:100%;height:100%;display:block}
.intro-shade{position:absolute;inset:-2px;z-index:1;background:linear-gradient(180deg,#f4f2ed,#ebe8e1 78%,#dfdbd3);box-shadow:inset 0 -1px 0 #cfc9bf}

.intro-shade:after{content:'';position:absolute;left:32%;right:32%;bottom:11px;height:5px;border-radius:3px;background:color-mix(in srgb,var(--text) 18%,transparent);box-shadow:0 1px 0 #ffffff80}
.intro-bezel{position:absolute;inset:calc(var(--pw)*-.085);border-radius:calc(var(--pw)*.54);border:calc(var(--pw)*.085) solid var(--trim);pointer-events:none;
  box-shadow:0 26px 50px -24px #1c344966,0 1px 2px #1c344914,inset 0 1px 4px #1c344924}
.intro-copy{position:absolute;left:0;right:0;top:calc(50% - var(--lift) + var(--ph)/2 + clamp(30px,6vh,56px));display:flex;flex-direction:column;align-items:center;gap:12px;text-align:center;color:var(--text)}
.intro-wordmark{display:flex;font:650 clamp(36px,5.6vmin,50px)/1.12 var(--sans);letter-spacing:-.045em;overflow:hidden;padding:0 .14em .08em}
.intro-letter,.intro-dot{display:inline-block}
.intro-dot{position:relative;color:var(--dot)}
.intro-dot.is-flashing{animation:strobe 1.1s ease-out}
.intro-tagline{margin:0;font:600 10.5px/1.2 var(--sans);letter-spacing:.24em;text-transform:uppercase;color:var(--muted)}
.intro-loader{display:flex;flex-direction:column;align-items:center;gap:10px;margin-top:12px}
.intro-track{position:relative;width:156px;height:2px;border-radius:2px;background:var(--line)}
.intro-track:before,.intro-track:after{content:'';position:absolute;top:50%;width:7px;height:7px;margin-top:-3.5px;border-radius:50%;background:var(--bg);border:1.5px solid var(--accent);box-sizing:border-box;z-index:1}
.intro-track:before{left:-3px}.intro-track:after{right:-3px}
.intro-fill{position:absolute;inset:0;border-radius:inherit;background:var(--accent);transform-origin:left;transform:scaleX(.04);transition:transform .8s cubic-bezier(.16,1,.3,1)}
.intro-plane{position:absolute;top:50%;left:4%;width:15px;height:15px;margin:-8px 0 0 -7px;color:var(--accent);z-index:2;transition:left .8s cubic-bezier(.16,1,.3,1)}
.intro-plane svg{display:block;width:100%;height:100%;filter:drop-shadow(0 2px 1px #1c344926)}
.intro-status{font:500 11px var(--sans);letter-spacing:.02em;color:var(--muted);min-height:14px}
html[data-intro] .intro:not(.is-playing) .intro-copy>*{opacity:0}
@media(max-height:560px){html[data-intro] .intro{--pw:clamp(92px,22vmin,140px);--lift:clamp(28px,12vh,64px)}.intro-tagline{display:none}.intro-copy{gap:6px}.intro-wordmark{font-size:32px}}

/* ---------- Split-flap airport codes ---------- */
.flap-row{display:inline-flex;isolation:isolate}
.flap{display:inline-block;position:relative;text-align:center;transform-origin:50% 54%;backface-visibility:hidden}
.flap:before,.flap:after{content:'';position:absolute;pointer-events:none;opacity:0;transition:opacity .22s ease-out}
.flap:before{inset:.1em .015em .04em;border-radius:.09em;background:color-mix(in srgb,var(--text) 7%,transparent);z-index:-1}
.flap:after{left:.015em;right:.015em;top:54%;height:1px;background:color-mix(in srgb,var(--text) 16%,transparent)}
.flap.is-live:before,.flap.is-live:after{opacity:1;transition:none}

/* ---------- Letters, bursts and ripples ---------- */
.letters-word{display:inline-block;white-space:nowrap}
.letter{display:inline-block}
.burst{position:fixed;width:0;height:0;z-index:70;pointer-events:none}
.burst i{position:absolute;left:0;top:0;width:6px;height:6px;border-radius:1px}
.mark-ripple{position:absolute;inset:-3px;border-radius:50%;border:2px solid currentColor;pointer-events:none}
.result-points strong{display:inline-block;transform-origin:left center}

/* ---------- Gliding tab indicators ---------- */
.has-glide{position:relative}
.glide{position:absolute;left:0;bottom:0;height:2px;border-radius:2px;background:currentColor;pointer-events:none;
  transition:transform .55s cubic-bezier(.3,1.3,.4,1),width .55s cubic-bezier(.3,1.3,.4,1),opacity .2s}
.main-nav .glide{display:none}
html[data-theme=minimal] .main-nav .glide{display:block;background:#244c66;bottom:0}
html[data-theme=minimal] .main-nav.has-glide .nav-button.active{border-bottom-color:transparent}
html[data-theme][data-layout] .workspace .mobile-makers .glide{height:3px;border-radius:0;background:var(--picker-accent)}
html[data-theme][data-layout] .workspace .mobile-makers.has-glide .maker-tab[aria-pressed=true]{box-shadow:none}

/* ---------- Lock-in shimmer ---------- */
#submit-guess{position:relative;overflow:hidden}
#submit-guess.is-locking:after{content:'';position:absolute;inset:0;pointer-events:none;background:linear-gradient(100deg,transparent 25%,#ffffff59 50%,transparent 75%);animation:shimmer .62s cubic-bezier(.4,0,.2,1) forwards}

@media(prefers-reduced-motion:no-preference){
  /* Tactile press and hover feedback. Immediate, never delayed. */
  .primary-button,.secondary-button{transition:transform .22s cubic-bezier(.3,1.6,.5,1),background-color .15s,border-color .15s,color .15s,box-shadow .15s}
  .primary-button:active:not(:disabled),.secondary-button:active:not(:disabled){transform:scale(.982)}
  .primary-button>.icon:last-child{transition:transform .38s cubic-bezier(.3,1.6,.5,1)}
  .primary-button:hover:not(:disabled)>.icon:last-child{transform:translateX(3px)}
  /* Selection swaps instantly, so the old and new choice are never highlighted together; only the press moves. */
  html[data-theme][data-layout] .workspace .roster-choice{transition:transform .2s cubic-bezier(.3,1.6,.5,1)}
  html[data-theme][data-layout] .workspace .roster-choice:active:not(:disabled){transform:scale(.965)}
  /* Family chips cascade whenever a manufacturer's roster appears; variants deal in from the left. */
  .family-choice{animation:chip-in .36s cubic-bezier(.16,1,.3,1) backwards;animation-delay:calc(var(--i,0)*18ms)}
  .variant-choice{animation:deal-in .2s cubic-bezier(.16,1,.3,1) backwards;animation-delay:calc(var(--i,0)*16ms)}
  .variant-choice[aria-pressed=true] .choice-check{animation:check-pop .46s cubic-bezier(.3,1.6,.5,1)}
  /* Surfaces arrive on expo-out. */
  .modal[open]{animation:modal-in .38s cubic-bezier(.16,1,.3,1)}
  .modal[open]::backdrop{animation:fade-in .32s ease-out}
  .toast:not([hidden]){animation:toast-in .5s cubic-bezier(.16,1,.3,1)}
  .appearance-menu[open] .appearance-options{animation:menu-in .26s cubic-bezier(.16,1,.3,1);transform-origin:top right}
  .connection-error:not([hidden]){animation:toast-in .5s cubic-bezier(.16,1,.3,1)}
  /* The wordmark's gold dot is a beacon: a double strobe flash every six seconds. The glow is its own
     layer animating opacity only, so it never repaints text. */
  html[data-theme=minimal] .brand-dot{position:relative}
  html[data-theme=minimal] .brand-dot:after{content:'';position:absolute;left:50%;bottom:.16em;width:.5em;height:.5em;margin-left:-.25em;border-radius:50%;background:radial-gradient(circle,#e7c59bcc,#ad865a00 70%);opacity:0;pointer-events:none;animation:beacon 6s 2.5s infinite;will-change:opacity}
  /* Sound is on but the browser is waiting for a first interaction: a ring breathes out from the speaker.
     It animates transform and opacity only, on the compositor. */
  .sound-toggle{position:relative}
  html:not([data-intro])[data-sound=quiet] .sound-toggle[aria-pressed=true]:not(:disabled):after{content:'';position:absolute;inset:4px;border-radius:50%;border:1.5px solid var(--lime);pointer-events:none;animation:sound-wait 2.8s ease-out 1s infinite;will-change:transform,opacity}
}
@keyframes chip-in{from{opacity:0;transform:translateY(7px) scale(.97)}}
@keyframes deal-in{from{opacity:0}}
@keyframes check-pop{0%{transform:scale(0) rotate(-20deg)}60%{transform:scale(1.25)}100%{transform:none}}
@keyframes modal-in{from{opacity:0;transform:translateY(14px) scale(.985)}}
@keyframes fade-in{from{opacity:0}}
@keyframes toast-in{from{opacity:0;translate:0 14px}}
@keyframes menu-in{from{opacity:0;transform:translateY(-6px) scale(.98)}}
@keyframes shimmer{from{transform:translateX(-100%)}to{transform:translateX(100%)}}
@keyframes beacon{0%,90%,92.4%,93.6%,96%,100%{opacity:0;transform:scale(.6)}91%,94.6%{opacity:1;transform:scale(1.6)}}
@keyframes strobe{0%,22%,44%,100%{text-shadow:none}8%,32%{text-shadow:0 0 6px #fff7e8,0 0 18px #ad865acc}}
@keyframes sound-wait{0%{opacity:.5;transform:scale(.7)}70%,100%{opacity:0;transform:scale(1.45)}}
