/* The interactive demo (player.js): video, subtitles, cursor, phone mockup.
   Lifted verbatim from the old single-page site; the page around it lives in site.css. */
:root {
  --ink:        #080A0E;
  --ink-2:      #0D1116;
  --surface:    #141A22;
  --surface-2:  #1B222C;
  --hairline:   #232B37;

  --text:       #F4F6F9;
  --text-soft:  #97A2B2;
  --text-faint: #5A6472;

  --amber:      #F0A93B;
  --amber-soft: #3A2A12;
  --amber-ink:  #10131A;
  --mint:       #3ED8B0;

  /* The phone mockup is not styled to the page. It is styled to the app, so
     these are the exact values from Theme.swift's light palette. Change one
     there and it should change here. */
  --app-bg:        #F7F5F0;
  --app-surface:   #FFFFFF;
  --app-surface-2: #EFEAE0;
  --app-hairline:  #E3DBCE;
  --app-ink:       #14181F;
  --app-ink-soft:  #5B6472;
  --app-ink-faint: #656C79;
  --app-accent:    #C77D12;
  --app-accent-2:  #FBEBD2;
  --app-mint:      #0E7A63;
  --app-blue:      #2F6FB5;
  --app-clay:      #8A6552;

  --sans: "Figtree", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  /* Serif is reserved, here as in the app, for vocabulary being learned. */
  --serif: "Newsreader", ui-serif, Georgia, "Times New Roman", serif;

  --ease: cubic-bezier(.16,1,.3,1);
}

.stage {
  position: relative;
  min-height: 100svh;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(20px, 3.4vw, 54px);
  align-items: center;
  padding: clamp(64px, 7vh, 92px) clamp(18px, 4vw, 56px) clamp(48px, 6vh, 70px);
  max-width: 1520px;
  margin-inline: auto;
}
@media (max-width: 1040px) {
  .stage { grid-template-columns: 1fr; justify-items: center; gap: 26px; }
}

/* The brand sits above everything, small. The demo is the hero, not a logo. */

.player { width: 100%; min-width: 0; }

.plate {
  border-radius: 14px;
  overflow: hidden;
  background: #000;
  border: 1px solid var(--hairline);
  box-shadow: 0 40px 90px rgba(0,0,0,.62);
}

.video {
  position: relative;
  aspect-ratio: 16 / 9;
  background:
    radial-gradient(85% 70% at 50% 22%, #1E2A3C 0%, #121820 48%, #070A0E 100%);
  overflow: hidden;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: 0 clamp(14px, 2.6vw, 34px) clamp(16px, 3.2vh, 34px);
}

/* Suggestion of a scene, drawn rather than shipped: no image to load, and it
   cannot be mistaken for a real video someone else made. */
.video::before {
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(26% 34% at 30% 34%, rgba(240,169,59,.16), transparent 68%),
    radial-gradient(24% 32% at 71% 28%, rgba(62,216,176,.12), transparent 68%),
    radial-gradient(60% 40% at 50% 100%, rgba(0,0,0,.55), transparent 70%);
}
/* A slow drifting grain, so the frame is never completely static. */
.video::after {
  content: "";
  position: absolute; inset: -40%;
  background-image:
    radial-gradient(rgba(255,255,255,.055) 1px, transparent 1px);
  background-size: 46px 46px;
  animation: drift 26s linear infinite;
  opacity: .5;
}
@keyframes drift { to { transform: translate(46px, 46px); } }

.video-title {
  position: absolute; top: 0; left: 0; right: 0; z-index: 3;
  padding: 14px clamp(14px, 2.6vw, 26px);
  display: flex; align-items: center; gap: 11px;
  background: linear-gradient(rgba(0,0,0,.62), transparent);
}
.avatar {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  background: linear-gradient(140deg, var(--amber), #C0761A);
  display: grid; place-items: center;
  font-weight: 800; font-size: 12px; color: var(--amber-ink);
}
.video-title b { font-size: 13.5px; font-weight: 600; display: block; letter-spacing: -.01em; }
.video-title span { font-size: 11.5px; color: rgba(255,255,255,.55); }
.live {
  margin-left: auto; display: flex; align-items: center; gap: 6px;
  font-size: 11px; font-weight: 700; letter-spacing: .1em; color: rgba(255,255,255,.6);
}
.live i { width: 6px; height: 6px; border-radius: 50%; background: var(--amber); animation: blink 1.9s infinite; }
@keyframes blink { 0%,100% { opacity: 1; } 50% { opacity: .25; } }

/* ------------------------------------------------------- subtitles ------ */
.subs { position: relative; z-index: 4; display: grid; gap: 7px; justify-items: center; text-align: center; }

.sub {
  display: inline-block; max-width: 100%;
  padding: .16em .55em; border-radius: 6px;
  background: rgba(6,8,11,.62);
  text-shadow: 0 1px 4px rgba(0,0,0,.9);
}
.sub-de { font-size: clamp(15px, 2.15vw, 27px); font-weight: 600; color: #fff; }
.sub-en { font-size: clamp(12.5px, 1.6vw, 19px); font-weight: 400; color: #FFE1A3; }

.w {
  position: relative;
  border-radius: 4px; padding: 0 .05em; cursor: pointer;
  transition: background .14s, color .14s, box-shadow .14s;
}
.w:hover { background: rgba(255,255,255,.2); box-shadow: 0 0 0 1px rgba(255,255,255,.3); }
.w.kept { background: var(--amber); color: var(--amber-ink); box-shadow: 0 0 0 1px var(--amber); }

.ripple {
  position: absolute; left: 50%; top: 50%;
  width: 12px; height: 12px; margin: -6px 0 0 -6px;
  border-radius: 50%; border: 2px solid var(--amber);
  pointer-events: none;
  animation: ripple .6s var(--ease) forwards;
}
@keyframes ripple { to { transform: scale(6); opacity: 0; } }

/* ---------------------------------------------------------- cursor ----- */
.cursor {
  position: absolute; top: 0; left: 0; z-index: 5;
  width: 22px; height: 22px; margin: -2px 0 0 -2px;
  pointer-events: none;
  opacity: 0;
  transition: opacity .35s;
  will-change: transform;
}
.cursor svg { width: 100%; height: 100%; display: block; filter: drop-shadow(0 2px 5px rgba(0,0,0,.7)); }
.cursor.clicking { animation: press .24s ease-out; }
@keyframes press { 50% { transform-origin: 0 0; scale: .82; } }

/* ---------------------------------------------------------- controls --- */
.controls {
  background: var(--ink-2);
  border-top: 1px solid var(--hairline);
  padding: 10px clamp(12px, 2vw, 18px) 12px;
}
.scrubber { height: 24px; display: flex; align-items: center; cursor: pointer; }
.track { position: relative; height: 3px; width: 100%; background: rgba(255,255,255,.16); border-radius: 2px; overflow: hidden; }
.fill { position: absolute; inset: 0; background: var(--amber); transform-origin: 0 50%; transform: scaleX(0); }
.crow { display: flex; align-items: center; gap: 13px; margin-top: 7px; }
.iconbtn {
  width: 30px; height: 30px; border: 0; border-radius: 8px;
  background: transparent; color: var(--text); cursor: pointer;
  display: grid; place-items: center; transition: background .2s;
}
.iconbtn:hover { background: rgba(255,255,255,.09); }
.iconbtn svg { width: 15px; height: 15px; fill: currentColor; }
.iconbtn .play-i { display: none; }        /* playing: offer Pause */
.iconbtn.paused .play-i { display: block; }
.iconbtn.paused .pause-i { display: none; }
.time { font-size: 12px; color: var(--text-soft); font-variant-numeric: tabular-nums; }
.kept-pill {
  margin-left: auto; display: flex; align-items: center; gap: 7px;
  font-size: 12px; font-weight: 600; color: var(--amber);
  background: var(--amber-soft); padding: 4px 11px; border-radius: 999px;
}
.kept-pill b { font-variant-numeric: tabular-nums; }

.caption {
  margin-top: 14px; font-size: 13px; color: var(--text-faint); text-align: center;
}
.caption b { color: var(--text-soft); font-weight: 600; }

/* ============================================================= phone ===== */
.phone { position: relative; z-index: 4; }

/* A titanium iPhone, built rather than photographed.
   Drawn in CSS so it scales to any width, needs no asset, and keeps a LIVE
   app running inside the screen. A device-frame PNG would flatten that back
   into a picture. Proportions follow a 16 Pro: corner radius is ~13% of the
   body width, and the rail is a hair wider than the glass. */
.frame {
  position: relative;
  width: clamp(244px, 25vw, 300px);
  aspect-ratio: 9 / 19.5;
  border-radius: 13.6%/6.4%;
  padding: 11px;
  /* Brushed titanium: alternating warm and cool bands across the rail, with
     hard stops where the chamfer catches the light. */
  background:
    linear-gradient(100deg,
      #3E4650 0%, #8C949E 4%, #C6CCD4 8%, #6E7681 13%,
      #454D57 26%, #3A424C 50%, #454D57 74%,
      #6E7681 87%, #C6CCD4 92%, #8C949E 96%, #3E4650 100%);
  box-shadow:
    0 1px 0 rgba(255,255,255,.34) inset,
    0 -1px 0 rgba(0,0,0,.5) inset,
    0 50px 90px -20px rgba(0,0,0,.72),
    0 18px 40px -12px rgba(0,0,0,.5);
}

/* The black glass that sits between the rail and the display. */
.frame::before {
  content: "";
  position: absolute; inset: 6px;
  border-radius: 12.4%/5.9%;
  background: #05070A;
  box-shadow: 0 0 0 1px rgba(0,0,0,.85);
}

/* Side buttons. Left rail carries the action button and the volume pair;
   the right rail carries the side button, lower down, as on the real device. */
.btn-side {
  position: absolute;
  width: 2.5px;
  border-radius: 2px;
  background: linear-gradient(180deg, #59616B, #343B44);
  box-shadow: -1px 0 2px rgba(0,0,0,.55);
}
.btn-action { left: -3px; top: 15%;   height: 4.1%; }
.btn-volup  { left: -3px; top: 22.5%; height: 6.6%; }
.btn-voldn  { left: -3px; top: 31%;   height: 6.6%; }
.btn-power  {
  right: -3px; top: 25%; height: 9.4%;
  background: linear-gradient(180deg, #59616B, #343B44);
  box-shadow: 1px 0 2px rgba(0,0,0,.55);
}

/* A glint on the glass, confined to the top corner.
   An earlier version swept the whole panel at 9% white, which over a WHITE
   app just fogged the text. On a light screen the reflection has to stay at
   the edge, where there is no content to wash out. */
.glass {
  position: absolute; inset: 11px;
  border-radius: 12.4%/5.9%;
  pointer-events: none; z-index: 8;
  background: linear-gradient(118deg,
    rgba(255,255,255,.5) 0%,
    rgba(255,255,255,.13) 3.5%,
    rgba(255,255,255,0) 9%,
    rgba(255,255,255,0) 100%);
}

@media (max-width: 1040px) { .frame { width: min(264px, 70vw); } }

.screen {
  position: relative; height: 100%;
  border-radius: 11.4%/5.4%; overflow: hidden;
  background: var(--app-bg);
  color: var(--app-ink);
  display: flex; flex-direction: column;
  transition: transform .4s var(--ease);
}
.screen.bump { transform: scale(1.014); }

.island {
  position: absolute; top: 9px; left: 50%; transform: translateX(-50%);
  width: 74px; height: 21px; border-radius: 999px; background: #000; z-index: 6;
}

/* Large title, the way the app's navigation bar renders it. */
.phead { padding: 46px 16px 10px; }
.phead b { font-size: 22px; font-weight: 800; letter-spacing: -.03em; display: block; }
.phead i { font-style: normal; font-size: 11px; color: var(--app-ink-faint); }

.plist { flex: 1; overflow: hidden; padding: 6px 12px; display: flex; flex-direction: column; gap: 6px; }
.pempty { padding: 24px 12px; text-align: center; color: var(--app-ink-faint); font-size: 12px; line-height: 1.5; }

/* One saved word, mirroring the Words tab: state dot, serif word, meaning. */
.prow {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 11px; border-radius: 13px;
  background: var(--app-surface);
  border: 1px solid var(--app-hairline);
  animation: prow-in .42s var(--ease);
}
@keyframes prow-in { from { opacity: 0; transform: translateY(-8px) scale(.94); } to { opacity: 1; transform: none; } }
.pdot { width: 7px; height: 7px; border-radius: 50%; background: var(--app-blue); flex: none; }
.pwrap { display: grid; gap: 1px; min-width: 0; }
.pword { font-family: var(--serif); font-size: 15px; font-weight: 600; color: var(--app-ink); line-height: 1.2; }
.pgloss { font-size: 10.5px; color: var(--app-ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pnew { margin-left: auto; font-size: 9px; font-weight: 700; color: var(--app-accent); flex: none; }

/* Tab bar, matching the app's four tabs. */
.ptabs {
  display: flex; border-top: 1px solid var(--app-hairline);
  background: var(--app-surface); padding: 7px 4px 15px;
}
.ptab { flex: 1; display: grid; place-items: center; gap: 2px; font-size: 9px; color: var(--app-ink-faint); }
.ptab.on { color: var(--app-accent); }
.ptab svg { width: 15px; height: 15px; fill: currentColor; }

/* --- the flashcard the word becomes ------------------------------------- */
.pcardwrap {
  position: absolute; inset: 0; z-index: 4;
  background: var(--app-bg);
  display: flex; flex-direction: column;
  padding: 46px 13px 16px;
  opacity: 0; pointer-events: none;
  transform: translateY(10px);
  transition: opacity .5s var(--ease), transform .5s var(--ease);
}
.screen.showing-card .pcardwrap { opacity: 1; transform: none; }

.pcounts { display: flex; gap: 5px; margin-bottom: 11px; }
.pcount { font-size: 9.5px; font-weight: 700; padding: 3px 8px; border-radius: 999px; }
.pc-new { color: var(--app-blue); background: rgba(47,111,181,.13); }
.pc-lrn { color: var(--app-clay); background: rgba(138,101,82,.13); }
.pc-due { color: var(--app-mint); background: rgba(14,122,99,.13); }

.pcard { flex: 1; position: relative; transform-style: preserve-3d; transition: transform .72s var(--ease); }
.pcard.flipped { transform: rotateY(180deg); }
.pface {
  position: absolute; inset: 0; backface-visibility: hidden;
  border-radius: 20px; border: 1px solid var(--app-hairline);
  background: var(--app-surface);
  box-shadow: 0 8px 22px rgba(20,24,31,.07);
  display: grid; place-content: center; align-content: center; gap: 10px;
  padding: 16px; text-align: center;
}
.pback { transform: rotateY(180deg); }
.cardword { font-family: var(--serif); font-size: 25px; font-weight: 600; color: var(--app-ink); }
.cardctx {
  font-size: 10.5px; color: var(--app-ink-soft); line-height: 1.45;
  background: var(--app-surface-2); padding: 8px 10px; border-radius: 9px;
}
.cardgloss { font-family: var(--serif); font-size: 22px; font-weight: 600; color: var(--app-accent); }
.cardhint { font-size: 10px; color: var(--app-ink-faint); }

.pgrades { display: flex; gap: 4px; margin-top: 11px; }
.pg { flex: 1; text-align: center; padding: 8px 0 6px; border-radius: 10px; display: grid; gap: 1px; }
.pg b { font-size: 9.5px; font-weight: 700; }
.pg span { font-size: 9px; opacity: .8; }
.pg1 { color: var(--app-clay); background: rgba(138,101,82,.13); }
.pg2 { color: #9A7B2E; background: rgba(154,123,46,.13); }
.pg3 { color: var(--app-mint); background: rgba(14,122,99,.13); }
.pg4 { color: var(--app-blue); background: rgba(47,111,181,.13); }

/* --- hear it again ------------------------------------------------------
   The card's back carries the line it came from and the second it was said.
   This is the feature nothing else in the category has, so it is on the face
   of the card rather than behind a menu. */
.cardlisten {
  display: flex; align-items: center; gap: 6px; justify-self: center;
  font-size: 10px; font-weight: 700; color: var(--app-accent);
  background: rgba(199,125,18,.11); padding: 6px 11px; border-radius: 999px;
}
.cardlisten svg { width: 9px; height: 9px; fill: currentColor; }

/* The line coming back when "Hear it again" is used: the player really does
   return to the second it was said, so the subtitle it came from lights up
   rather than the card merely claiming it would. */
.sub-de.replay { animation: replay .9s var(--ease); }
@keyframes replay {
  0%, 100% { box-shadow: none; }
  25%, 70% { box-shadow: 0 0 0 3px rgba(240,169,59,.55); }
}

/* Netflix, wearing its own chrome. Both sites are real and the extension
   treats them the same way, which is the claim the beat makes. */
.video-title.is-netflix .avatar { background: #E50914; color: #fff; }
.video-title.is-netflix .live { display: none; }
.cardsrc { font-size: 9px; color: var(--app-ink-faint); }

/* --- the cloze: the same card, asked harder ----------------------------- */
.screen.cloze .cardword { display: none; }
/* The context block carries the whole sentence, which on a cloze card is the
   answer sitting under the question. The gap *is* the sentence here, so the
   block goes. */
.screen.cloze .cardctx { display: none; }
.cardcloze { display: none; font-family: var(--serif); font-size: 17px;
             font-weight: 600; line-height: 1.4; color: var(--app-ink); }
.screen.cloze .cardcloze { display: block; }
.cardcloze u { text-decoration: none; border-bottom: 2px solid var(--app-accent);
               padding: 0 16px; }

/* --- a screen for anything that is not the card ------------------------- */
.psheet {
  position: absolute; inset: 0; z-index: 5;
  background: var(--app-bg); display: flex; flex-direction: column;
  padding: 46px 14px 16px;
  opacity: 0; pointer-events: none; transform: translateY(10px);
  transition: opacity .5s var(--ease), transform .5s var(--ease);
}
.screen.showing-read .preadwrap,
.screen.showing-grid .pgridwrap { opacity: 1; transform: none; }
.psheet h4 { font-size: 17px; font-weight: 800; letter-spacing: -.02em; margin: 0 0 2px; }
.psheet .psub { font-size: 9.5px; color: var(--app-ink-faint); margin: 0 0 12px; }

/* The library page. Every word is tappable, which is the whole claim, so the
   ones that carry it are marked and one of them is already kept. */
.pbook {
  flex: 1; overflow: hidden; font-family: var(--serif);
  font-size: 12.5px; line-height: 1.72; color: var(--app-ink);
  background: var(--app-surface); border: 1px solid var(--app-hairline);
  border-radius: 14px; padding: 13px 13px 0;
}
.pbook t { border-bottom: 1px dotted var(--app-ink-faint); }
.pbook k { background: rgba(240,169,59,.34); border-radius: 3px;
           box-shadow: 0 0 0 2px rgba(240,169,59,.34); }

/* The grid of days. Amber for the days you turned up and nothing at all for
   the ones you did not, because the absence is not a debt. */
.pgrid { display: grid; grid-template-columns: repeat(18, 1fr); gap: 3px;
         margin: 2px 0 12px; }
.pgrid i { display: block; aspect-ratio: 1; border-radius: 2.5px;
           background: var(--app-surface-2); }
.pgrid i.l1 { background: rgba(240,169,59,.34); }
.pgrid i.l2 { background: rgba(240,169,59,.62); }
.pgrid i.l3 { background: var(--app-accent); }
.pstats { display: flex; gap: 7px; }
.pstat { flex: 1; background: var(--app-surface); border: 1px solid var(--app-hairline);
         border-radius: 12px; padding: 9px 8px; text-align: center; }
.pstat b { display: block; font-size: 16px; font-weight: 800; letter-spacing: -.02em; }
.pstat span { font-size: 8.5px; color: var(--app-ink-faint); }
.pnote { margin: 11px 0 0; font-size: 9.5px; line-height: 1.5;
         color: var(--app-ink-soft); text-align: center; }

/* --------------------------------------------------- the flying word --- */
.flylayer { position: absolute; inset: 0; z-index: 20; pointer-events: none; }
.fly {
  position: absolute;
  font-family: var(--serif); font-size: 17px; font-weight: 700;
  color: var(--amber-ink); background: var(--amber);
  padding: 3px 11px; border-radius: 999px;
  box-shadow: 0 8px 26px rgba(240,169,59,.4);
  white-space: nowrap;
}

/* ============================================================== band =====
   The argument between the demo and the offer: why a gap costs nothing, and
   why a word from a scene outlives a word from a list. It borrows the card
   language of .research and .reading below rather than inventing a second
   one — this is the same page making the same case earlier. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}
