/* One stylesheet for the whole site.
   Tokens match the extension's, in src/ui/shared.css, so the page and the
   product are visibly the same thing. */
:root {
  color-scheme: light dark;
  --surface: #fbfaf6;
  --raised: #ffffff;
  --sunken: #f2f0e9;
  --line: #e5e1d6;
  --ink: #1a1916;
  --ink-2: #55534a;
  --ink-3: #7c7a70;
  --accent: #8a6a12;
  --accent-soft: #faf1d8;
  --gold: #e0ac3a;
  --amber: rgba(176, 122, 40, 0.85);
  --terracotta: rgba(182, 92, 76, 0.95);
  --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --jp: "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic", Meiryo, sans-serif;
}
@media (prefers-color-scheme: dark) {
  :root {
    --surface: #1a1917; --raised: #232220; --sunken: #141312; --line: #34322c;
    --ink: #f0eee6; --ink-2: #b6b3a7; --ink-3: #8a877c;
    --accent: #d8ac41; --accent-soft: #38300f; --gold: #e0ac3a;
    --amber: rgba(200, 150, 60, 0.85);
  }
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0; background: var(--surface); color: var(--ink);
  font: 17px/1.6 var(--font); -webkit-font-smoothing: antialiased;
}
.wrap { max-width: 760px; margin: 0 auto; padding: 0 24px; }

/* ------------------------------------------------------------------- hero */

header { padding: 84px 0 20px; text-align: center; }
.mark {
  display: inline-grid; place-items: center; width: 54px; height: 54px;
  border-radius: 13px; background: var(--ink); color: var(--gold);
  font: 600 30px/1 var(--jp); margin-bottom: 30px;
}
h1 {
  font-size: clamp(32px, 6.4vw, 52px); line-height: 1.08;
  letter-spacing: -0.028em; margin: 0 0 18px; font-weight: 700;
}
.lede {
  font-size: clamp(17px, 2.4vw, 20px); line-height: 1.55; color: var(--ink-2);
  margin: 0 auto 40px; max-width: 27em;
}

/* --------------------------------------------------------------- sections */

section { padding: 66px 0; border-top: 1px solid var(--line); }
section:first-of-type { border-top: 0; }
h2 {
  font-size: clamp(21px, 3.4vw, 27px); line-height: 1.2; letter-spacing: -0.02em;
  margin: 0 0 8px; text-align: center; font-weight: 650;
}
.sub {
  text-align: center; color: var(--ink-3); font-size: 15px;
  margin: 0 auto 34px; max-width: 26em;
}

/* --------------------------------------------------------------- the stage

   Every figure sits on one of these: a page, abstracted down to the one line
   that matters. */
.stage {
  background: var(--raised); border: 1px solid var(--line); border-radius: 14px;
  padding: 34px 30px; position: relative; overflow: hidden;
}
.stage-line {
  font-size: clamp(17px, 2.6vw, 21px); line-height: 2.5; margin: 0;
  text-align: center;
}

/* A word on the stage, in whichever of the three states it is in. */
.w {
  --mark: var(--amber);
  --mark-style: dotted;
  position: relative; font-family: var(--jp);
  border-bottom: 2px var(--mark-style) var(--mark);
  border-radius: 2px; padding: 0 1px; cursor: help;
  transition: background-color 120ms ease, border-color 200ms ease;
}
.w:hover, .w:focus-visible { background: rgba(176, 122, 40, 0.13); outline: none; }
.w:focus-visible { box-shadow: 0 0 0 2px var(--mark); }
.w rt { font-size: 0.48em; opacity: 0.7; font-weight: 400; }
.w[data-read="true"]   { --mark: var(--gold); --mark-style: solid; }
.w[data-helped="true"] { --mark: var(--terracotta); --mark-style: dashed; }

.w.holding { animation: hold 550ms linear forwards; }
@keyframes hold {
  from { box-shadow: 0 0 0 0 rgba(0,0,0,0); }
  to   { box-shadow: 0 0 11px 3px var(--gold); }
}
.w.done {
  display: inline-block; transform-origin: 50% 55%;
  animation: flip 900ms cubic-bezier(0.2, 0.7, 0.3, 1);
}
@keyframes flip {
  0%   { transform: rotateX(0deg);   color: inherit; box-shadow: 0 0 11px 3px var(--gold); }
  40%  { transform: rotateX(88deg);  color: inherit; box-shadow: 0 0 17px 5px var(--gold); }
  41%  { transform: rotateX(-88deg); color: var(--gold); }
  70%  { transform: rotateX(0deg);   color: var(--gold); box-shadow: 0 0 8px 2px var(--gold); }
  100% { transform: rotateX(0deg);   color: inherit; box-shadow: 0 0 0 0 rgba(0,0,0,0); }
}

/* Off screen, animations stop. A page of loops all running at once competes
   with itself and the one being looked at loses. Pausing rather than starting
   means the page still works with the script blocked. */
.reel.paused *, .reel.paused { animation-play-state: paused !important; }

/* --------------------------------------------- figure one: the whole thing

   Page opens, a word turns Japanese, you rest on it, it turns gold. The entire
   product in eight seconds and no sentences. */
.reel .swap { position: relative; display: inline-block; }
.reel .en, .reel .ja {
  display: inline-block; transform-origin: 50% 55%; backface-visibility: hidden;
}
/* The Japanese is the one in the flow, so the line is sized by the state it
   spends most of the loop in and the English overlays it for the first second.
   The other way round leaves a hole where "cat" used to be. */
/* Neither of the two faces is in the flow. An invisible copy of the wider one
   holds the space instead, so the line does not reflow as the word turns over
   and neither face spills into the words beside it. */
.reel .sizer { visibility: hidden; }
.reel .ja, .reel .en {
  position: absolute; left: 50%; top: 0; transform: translateX(-50%);
  white-space: nowrap;
}

.reel .en { animation: face-out 8s ease-in-out infinite; }
.reel .ja { animation: face-in  8s ease-in-out infinite; }
@keyframes face-out {
  0%, 12%   { transform: translateX(-50%) rotateX(0deg);  opacity: 1; }
  17%, 100% { transform: translateX(-50%) rotateX(90deg); opacity: 0; }
}
@keyframes face-in {
  0%, 12%  { transform: translateX(-50%) rotateX(-90deg); opacity: 0; }
  17%      { transform: translateX(-50%) rotateX(0deg);   opacity: 1; }
  100%     { transform: translateX(-50%) rotateX(0deg);   opacity: 1; }
}

/* The underline beneath it, and the glow that fills while it is held. */
.reel .underline {
  position: absolute; left: 0; right: 0; bottom: -5px; height: 2px;
  border-radius: 2px; opacity: 0;
  background-image: linear-gradient(to right, var(--amber) 0 2px, transparent 2px 5px);
  background-repeat: repeat-x;
  background-size: 5px 2px;
}
.reel .underline { animation: underline 8s ease-in-out infinite; }
@keyframes underline {
  /* Dotted amber while unread, solid gold once read: the extension's own
     language, so what is learned here is true there. */
  0%, 15%   { opacity: 0; background-size: 5px 2px; box-shadow: none; }
  20%, 44%  { opacity: 1; background-size: 5px 2px; box-shadow: none; }
  /* The hold: the glow builds. */
  56%       { opacity: 1; background-size: 5px 2px; box-shadow: 0 0 12px 3px var(--gold); }
  58%       { opacity: 1; background-size: 100% 2px; box-shadow: 0 0 18px 5px var(--gold); }
  70%, 100% { opacity: 1; background-size: 100% 2px; box-shadow: none; }
}
/* Swapping the gradient to a flat gold at the moment of the flip. */
.reel .underline { --line-fill: var(--amber); }
.reel .underline { animation-name: underline, underline-colour; }
@keyframes underline-colour {
  0%, 57%   { background-image: linear-gradient(to right, var(--amber) 0 2px, transparent 2px 5px); }
  58%, 100% { background-image: linear-gradient(to right, var(--gold) 0 100%); }
}
/* The word itself turns over as the hold completes. */
.reel .swap { animation: turn 8s ease-in-out infinite; }
@keyframes turn {
  0%, 56%  { transform: rotateX(0deg); }
  60%      { transform: rotateX(88deg); }
  61%      { transform: rotateX(-88deg); color: var(--gold); }
  68%      { transform: rotateX(0deg); color: var(--gold); }
  78%,100% { transform: rotateX(0deg); color: inherit; }
}

/* The pointer that arrives, waits, and leaves. */
.pointer {
  position: absolute; width: 19px; height: 19px; pointer-events: none;
  opacity: 0; z-index: 3;
}
.pointer svg { display: block; filter: drop-shadow(0 1px 2px rgba(0,0,0,0.3)); }
.reel .pointer { animation: pointer 8s ease-in-out infinite; }
@keyframes pointer {
  0%, 30%   { opacity: 0; transform: translate(64px, 42px); }
  36%       { opacity: 1; transform: translate(40px, 34px); }
  44%, 72%  { opacity: 1; transform: translate(6px, 12px); }
  80%       { opacity: 0; transform: translate(30px, 34px); }
  100%      { opacity: 0; transform: translate(64px, 42px); }
}

/* ------------------------------------------- figure two: the reading fades */

.fade-row { display: flex; justify-content: center; gap: 10px; flex-wrap: wrap; }
.fade-step {
  background: var(--sunken); border-radius: 10px; padding: 16px 20px 13px;
  min-width: 92px; text-align: center;
}
.fade-step ruby { font-family: var(--jp); font-size: 27px; }
.fade-step rt {
  font-size: 0.42em; opacity: 0.85; font-weight: 500; letter-spacing: 0.02em;
}
.fade-step rt .romaji { font-family: var(--font); opacity: 0.65; }
.fade-step .when { display: block; font-size: 11.5px; color: var(--ink-3); margin-top: 9px; }
.fade-step:last-child { background: var(--accent-soft); }

/* --------------------------------------------- figure three: it grows

   The same paragraph at three points in time. More Japanese each time, and
   never any harder, which is the one claim worth making and the hardest to
   make in words. */
.grow { display: grid; gap: 12px; }
.grow-row {
  background: var(--raised); border: 1px solid var(--line); border-radius: 12px;
  padding: 18px 20px; display: grid; gap: 4px;
  transition: opacity 520ms ease, transform 520ms ease;
}
.js .grow .grow-row { opacity: 0; transform: translateY(10px); }
.js .grow.play .grow-row { opacity: 1; transform: none; }
.js .grow.play .grow-row:nth-child(2) { transition-delay: 170ms; }
.js .grow.play .grow-row:nth-child(3) { transition-delay: 340ms; }
.grow .when { font-size: 11.5px; color: var(--ink-3); letter-spacing: 0.03em; text-transform: uppercase; }
.grow .text { font-size: 16px; line-height: 2.1; }
.grow-row:last-child { border-color: var(--gold); }

/* The bar showing what share of the line you can read, which stays flat while
   the Japanese share climbs. */
.bar { height: 5px; border-radius: 3px; background: var(--sunken); overflow: hidden; margin-top: 8px; }
.bar i { display: block; height: 100%; background: var(--gold); width: var(--w, 30%); transition: width 900ms ease 300ms; }
.js .grow .bar i { width: 0; }
.js .grow.play .bar i { width: var(--w, 30%); }

/* -------------------------------------------------------------- features */

.features {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(228px, 1fr));
}
.feature {
  background: var(--raised); border: 1px solid var(--line); border-radius: 12px;
  padding: 20px 20px 18px;
}
.feature .icon {
  width: 30px; height: 30px; border-radius: 8px; background: var(--accent-soft);
  color: var(--accent); display: grid; place-items: center; margin-bottom: 13px;
}
.feature .icon svg { width: 17px; height: 17px; }
.feature h3 { font-size: 15.5px; margin: 0 0 5px; font-weight: 650; line-height: 1.3; }
.feature p { font-size: 14px; line-height: 1.55; color: var(--ink-2); margin: 0; }

/* Things that need a key of your own, kept visually apart so nobody reads them
   as missing from the free part. */
.feature[data-optional] { background: transparent; border-style: dashed; }
.feature[data-optional] .icon { background: var(--sunken); color: var(--ink-3); }
.tag {
  display: inline-block; font-size: 10.5px; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--ink-3); border: 1px solid var(--line);
  border-radius: 20px; padding: 2px 8px; margin-left: 7px; vertical-align: 2px;
  font-weight: 600;
}

/* ----------------------------------------------------------- where it is at

   The honest numbers. A learner deciding whether to install this deserves to
   know the library is 984 words rather than find out in week three. */
.facts {
  display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  text-align: center;
}
.fact {
  background: var(--sunken); border-radius: 11px; padding: 17px 14px;
}
.fact b { display: block; font-size: 25px; line-height: 1.15; font-weight: 680; }
.fact span { display: block; font-size: 12.5px; color: var(--ink-3); margin-top: 5px; line-height: 1.4; }

/* ------------------------------------------------------------------- CTA */

.cta { text-align: center; }
.buttons { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-bottom: 14px; }
.button {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--accent); color: #fff; text-decoration: none;
  padding: 13px 24px; border-radius: 10px; font-weight: 600; font-size: 15.5px;
  border: 1px solid transparent;
}
.button:hover { filter: brightness(1.08); }
.button.secondary { background: transparent; color: var(--ink); border-color: var(--line-strong, var(--line)); }
.button svg { width: 18px; height: 18px; }
/* Not published yet. A button that looks live and is not is worse than one
   that says so. */
.button[aria-disabled="true"] {
  background: var(--sunken); color: var(--ink-3); border-color: var(--line);
  cursor: default; pointer-events: none; font-weight: 500;
}
.fine { font-size: 13.5px; color: var(--ink-3); margin: 0; }

/* ---------------------------------------------------------------- the card */

.card-pop {
  position: absolute; z-index: 50; min-width: 148px; max-width: 250px;
  background: var(--raised); border: 1px solid var(--line); border-radius: 10px;
  padding: 12px 14px; box-shadow: 0 10px 30px rgba(0,0,0,0.16);
  opacity: 0; visibility: hidden; transform: translateY(-4px);
  transition: opacity 110ms ease, transform 110ms ease, visibility 110ms;
  text-align: left;
}
.card-pop[data-open="true"] { opacity: 1; visibility: visible; transform: none; }
.cp-ja { font-family: var(--jp); font-size: 22px; line-height: 1.2; }
.cp-reading { font-family: var(--jp); font-size: 13px; color: var(--ink-2); margin-top: 3px; }
.cp-reading span { color: var(--ink-3); margin-left: 7px; font-family: var(--font); }
.cp-en { font-size: 14px; margin-top: 7px; }

/* --------------------------------------------------------------- the tally */

.tally {
  display: inline-flex; align-items: baseline; gap: 8px;
  background: var(--accent-soft); border-radius: 10px; padding: 9px 15px;
  font-size: 14px; color: var(--ink-2); opacity: 0.5;
  transition: opacity 220ms ease;
}
.tally[data-live="true"] { opacity: 1; }
.tally b { font-size: 20px; color: var(--ink); font-weight: 650; }

/* The privacy page is prose rather than demonstration, so it needs the plain
   document elements the landing page never uses. Left-aligned, because a wall
   of centred paragraphs is unreadable. */
.doc { text-align: left; padding-bottom: 40px; }
.doc header { text-align: left; padding-bottom: 8px; }
.doc h1 { font-size: clamp(28px, 5vw, 38px); }
.doc .lede { margin-left: 0; }
.doc h2 { text-align: left; font-size: 20px; margin: 44px 0 10px; }
.doc h3 { text-align: left; font-size: 16px; margin: 26px 0 6px; font-weight: 650; }
.doc p { margin: 0 0 14px; max-width: 36em; }
.doc ul { margin: 0 0 16px; padding-left: 20px; max-width: 36em; }
.doc li { margin-bottom: 7px; }
.doc a { color: var(--accent); }
code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.88em; background: var(--sunken); padding: 1px 5px; border-radius: 4px;
}

footer {
  padding: 34px 0 56px; border-top: 1px solid var(--line);
  font-size: 13px; color: var(--ink-3); text-align: center;
}
footer a { color: var(--ink-2); }

/* Motion is the whole point of this page, so switching it off has to leave the
   finished state rather than an empty box. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reel .en, .reel .ja, .reel .underline,
  .reel .swap, .reel .pointer { animation: none !important; }
  .reel .en { display: none; }
  .reel .ja { position: absolute; }
  .reel .underline { opacity: 1; background: var(--gold); }
  .reel .pointer { display: none; }
  .grow-row { opacity: 1; transform: none; transition: none; }
  .bar i { transition: none; }
  .w.holding { animation: none; box-shadow: 0 0 0 2px var(--gold); }
  .w.done { display: inline; animation: none; }
}
