/* Cyber Curio editorial website design.
 *
 * This layer sits on top of styles.css (tokens and primitives) and defines the
 * published visual design for both site profiles. It is organised by component,
 * and every selector appears once per breakpoint. When a value needs to change,
 * change it where it is declared — do not append an overriding block.
 *
 * Contents
 *   1  Document and layout shell
 *   2  Design tokens added by this layer
 *   3  Typography scale
 *   4  Header and navigation
 *   5  Hero
 *   6  Concept card scene
 *   7  Products
 *   8  Approach
 *   9  Content cards
 *  10  Contact and account dialogs
 *  11  Footer
 *  12  Interaction vocabulary
 *  13  Motion
 */

/* ------------------------------------------------------------------ *
 * 1  Document and layout shell
 * ------------------------------------------------------------------ */

html { scroll-behavior: auto; scroll-padding-top: 96px; }

/* The published design uses flat surfaces; the orbit field from styles.css is
 * not part of it. All three theme variants are named so no !important is needed. */
body,
:root[data-theme=dark] body,
:root:not([data-theme]) body { background-image: none; }

.hero::after { display: none; }

/* One hairline per top-level boundary, declared in one place. styles.css gives
 * the hero a bottom rule and nothing to the library or contact sections, which
 * left five section edges carrying three lines; the section that follows now
 * always draws the boundary, so adding or reordering a section cannot lose one. */
.home-page .hero { border-bottom: 0; }
.home-page .products,
.home-page .principles,
.home-page .home-library,
.home-page .contact { border-top: 1px solid var(--line); }

.shell { width: min(calc(100% - 112px), 1280px); }

@media (max-width: 1100px) { .shell { width: calc(100% - 64px); } }

@media (max-width: 760px) {
  html { scroll-padding-top: 84px; }
  .shell { width: calc(100% - 40px); }
}

/* ------------------------------------------------------------------ *
 * 2  Design tokens added by this layer
 * ------------------------------------------------------------------ */

:root {
  --soft-purple: #EAE5FA;
  --text: var(--ink);
  /* Status is its own semantic role, deliberately separate from the brand
   * colours: a product's availability is not a brand statement. */
  --status-ink: #4A4854;
  --status-surface: #ECEAE5;
  --status-line: #CFCBC4;
}

:root[data-theme=dark] {
  --soft-purple: #342B4F;
  --status-ink: #D8D4DF;
  --status-surface: #2E2C38;
  --status-line: #4A4754;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --soft-purple: #342B4F;
    --status-ink: #D8D4DF;
    --status-surface: #2E2C38;
    --status-line: #4A4754;
  }
}

/* ------------------------------------------------------------------ *
 * 3  Typography scale
 *
 * Latin display type is tightened; CJK glyphs already sit on a full em box and
 * crowd when tracking goes negative, so Chinese headings reset to normal.
 * Product names are Latin wordmarks in every locale and stay tightened.
 * ------------------------------------------------------------------ */

.home-page h1,
.home-page h2,
.home-page h3 { font-family: inherit; font-weight: 650; letter-spacing: -.025em; }

.home-page h2 { font-size: 46px; font-weight: 550; line-height: 1.3; max-width: 900px; }

/* styles.css lays section headings out as a two-column grid for a summary
 * column this design does not use. */
.section-heading { display: block; }

/* Listed one by one rather than as a blanket h1/h2/h3 reset: the Chinese pages
 * also carry Latin headings — product names, concept card titles, account
 * dialog titles — and those still want the tightening. */
html[lang=zh-CN] .home-page .hero-title,
html[lang=zh-CN] .home-page h2,
html[lang=zh-CN] .principle h3,
html[lang=zh-CN] .card-grid .card-title { letter-spacing: normal; }

@media (max-width: 1100px) { .home-page h2 { font-size: 38px; } }
@media (max-width: 760px) { .home-page h2 { font-size: 31px; } }

/* Section labels: readable, and quieter than the heading they introduce. */
.home-page .section .eyebrow,
.home-page .principles .eyebrow { font-size: 18px; font-weight: 600; line-height: 1.5; letter-spacing: .02em; }

/* Curio orange opens every section label. It never carries the label's text —
 * #FC7D55 is 2.35:1 on the warm canvas and fails at any size — so the rule is
 * orange and the word beside it stays in its own colour. */
.home-page .section .eyebrow::before,
.home-page .principles .eyebrow::before {
  content: "";
  display: inline-block;
  width: 34px;
  height: 3px;
  margin-right: 12px;
  background: var(--curio);
  vertical-align: middle;
}

.home-page .hero .eyebrow { font-size: 24px; font-weight: 600; line-height: 1.4; letter-spacing: .05em; }

@media (max-width: 760px) {
  .home-page .section .eyebrow,
  .home-page .principles .eyebrow { font-size: 16px; }
  .home-page .hero .eyebrow { font-size: 20px; }
}

/* ------------------------------------------------------------------ *
 * 4  Header and navigation
 * ------------------------------------------------------------------ */

/* The header bar itself is inert; the floating pill inside it takes the pointer. */
.site-header {
  height: 84px;
  z-index: 20;
  background: transparent;
  border-color: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  pointer-events: none;
}

.site-header .header-content {
  box-sizing: border-box;
  min-height: 84px;
  padding: 0 20px;
  border: 1px solid transparent;
  pointer-events: auto;
  /* The shape settles with overshoot so the bar reads as a solid object coming
   * to rest, not a value being interpolated. Colour and shadow stay linear —
   * overshooting a blur just looks like a glitch. */
  transition:
    transform .62s cubic-bezier(.34, 1.42, .52, 1),
    border-radius .62s cubic-bezier(.34, 1.42, .52, 1),
    background .34s ease,
    box-shadow .34s ease,
    backdrop-filter .34s ease;
}

.site-header.is-floating .header-content {
  position: relative;
  isolation: isolate;
  min-height: 68px;
  transform: translateY(12px);
  border-radius: 40px;
  border-color: transparent;
  /* 45% is the floor, not a taste call: below it the navigation stops being
   * readable where a saturated card scrolls under the bar. See the colour note
   * on `.is-floating .nav a` just below. */
  background: color-mix(in srgb, var(--canvas) 45%, transparent);
  backdrop-filter: blur(26px) saturate(188%) brightness(1.06);
  -webkit-backdrop-filter: blur(26px) saturate(188%) brightness(1.06);
  box-shadow:
    inset 0 1.5px 2px #ffffff6e,
    inset 0 0 10px #ffffff24,
    inset 0 -1px 2px #16151c10,
    0 2px 6px #16151c0a,
    0 12px 28px #16151c12,
    0 28px 56px #16151c08;
}

/* A thin bright rim along the top edge, fading out before the bottom: the part
 * of a curved transparent body that actually catches the light. */
.site-header.is-floating .header-content::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  border-radius: inherit;
  background: linear-gradient(168deg, #ffffff30, #ffffff0a 34%, transparent 62%, #ffffff10);
  box-shadow: inset 0 0 3px #ffffff38;
}

/* A translucent bar has no background of its own to guarantee contrast: whatever
 * scrolls under it becomes the text's background. styles.css sets navigation
 * links in --muted, which measures 1.6:1 against the deep purple product card
 * seen through the glass — unreadable, and it was already 2.0:1 before the glass
 * was opened up. Floating navigation therefore uses --ink (4.5:1 against that
 * same worst case) and the locale switch gets an opaque pill of its own. */
.site-header.is-floating .nav a,
.site-header.is-floating .nav [aria-current=location] { color: var(--ink); }

.site-header.is-floating .nav > a.locale-link,
.site-header.is-floating .js .nav-links a.locale-link {
  background: var(--raised);
  border-color: color-mix(in srgb, var(--line) 80%, transparent);
  color: var(--cyber-ui);
}

.brand { font-size: 24px; gap: 12px; }
.brand img { width: 46px; height: 36px; }

:root[data-theme=dark] .brand img { content: url('/assets/cyber-curio-mark-reverse.svg'); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .brand img { content: url('/assets/cyber-curio-mark-reverse.svg'); }
}

.nav-links { gap: 6px; }

.nav > a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 38px;
  padding: 8px 12px;
  border-radius: 9px;
  transition: background .18s ease, color .18s ease;
}

.nav-links > a { padding: 9px 10px; border-radius: 9px; transition: background .18s ease, color .18s ease, box-shadow .18s ease; }

.nav [aria-current=location] { color: var(--cyber-ui); text-decoration: underline; text-underline-offset: 8px; }
body:not(.home-page) .nav a[aria-current=page] { text-decoration: none; }

/* Site switch keeps a hairline boundary that is not part of its hover surface. */
.nav .site-switch,
.js .nav-links .site-switch { position: relative; margin-left: 12px; padding-left: 10px; border-left: 0; border-top: 0; margin-top: 0; }

.nav .site-switch::before {
  content: "";
  position: absolute;
  left: -9px;
  top: 50%;
  width: 1px;
  height: 20px;
  background: var(--line);
  transform: translateY(-50%);
  pointer-events: none;
}

.locale-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 24px;
  color: var(--ink);
}

/* `.nav > a` above gives every navigation target a 9px pill. The locale switch
 * keeps its round shape; written at matching specificity instead of !important. */
.nav > a.locale-link,
.js .nav-links a.locale-link { border-radius: 24px; }

.locale-link::before {
  content: '';
  display: inline-block;
  width: 18px;
  height: 18px;
  background: currentColor;
  mask: url('/assets/languages.svg') center/contain no-repeat;
}

.locale-link:hover { background: var(--soft-purple); color: var(--cyber-ui); }

/* Default size for every social target. The navigation uses a smaller one
 * below, and the contact section's account triggers a larger one; both are
 * declared after this so they win on source order. */
.social-list a { width: 36px; height: 36px; }

/* Social links ride in the navigation on reading pages only; the home page
 * carries them in the contact section instead. */
.nav-social {
  display: flex;
  flex-wrap: nowrap;
  gap: 4px;
  margin-left: 4px;
  padding-left: 12px;
  border-left: 1px solid var(--line);
}

.nav-social a { width: 32px; height: 32px; border: 0; background: transparent; transition: background .18s ease, color .18s ease, transform .18s ease, box-shadow .18s ease; }
.nav-social a::after { top: calc(100% + .65rem); bottom: auto; }
.nav-social .social-icon { width: 19px; height: 19px; }
.home-page .nav-social { display: none; }

@media (max-width: 1100px) and (min-width: 761px) {
  .site-header .header-content { width: calc(100% - 28px); gap: 12px; }
  .nav, .nav-links { gap: 10px; }
  .nav-links > a { padding: 8px 5px; }
  .nav-social { margin-left: 0; gap: 0; padding-left: 4px; }
  .nav-social a { width: 28px; }
}

@media (max-width: 760px) {
  .site-header { height: 68px; }
  .site-header .header-content { width: calc(100% - 20px); min-height: 68px; padding: 0 10px; gap: 12px; }
  .site-header.is-floating .header-content { min-height: 60px; border-radius: 24px; transform: translateY(8px); }
  .brand img { width: 32px; height: 30px; }
  .brand span { display: none; }
  .nav { gap: 8px; }
  .locale-link { font-size: 14px; padding: 9px; }
  .js .nav-links .site-switch { margin-left: 0; }
  .nav .site-switch::before { display: none; }
  .nav-social { width: 100%; margin: 6px 0 0; padding: 10px 0 0; border-left: 0; border-top: 1px solid var(--line); gap: 12px; }
  .nav-social a { width: 40px; height: 40px; }
}

@media (max-width: 420px) { .nav { gap: 6px; } }

/* ------------------------------------------------------------------ *
 * 5  Hero
 * ------------------------------------------------------------------ */

.home-page .hero-layout {
  position: relative;
  display: grid;
  grid-template-columns: 1.16fr 1fr;
  align-items: center;
  gap: 70px;
  min-height: 730px;
  padding: 42px 0 70px;
}

.home-page .hero-title {
  margin: 0;
  max-width: none;
  font-size: clamp(40px, 5.5vw, 84px);
  font-weight: 750;
  line-height: 1.32;
  letter-spacing: -.045em;
  text-wrap: initial;
}

/* Sized so "Everyone is more creative" holds one line at the hero's measure;
 * the sentence breaks where it was written to break, not where it runs out. */
html[lang=en] .hero-title { font-size: clamp(40px, 3.9vw, 58px); }
html[lang=en] .hero-title > span { display: block; }
/* The Chinese setting keeps each line whole; its tracking reset lives with the
 * other CJK headings in section 3. */
/* Each Chinese line stays whole, so the type has to be sized to the line rather
 * than the other way round: too large and the nowrap column squeezes the art
 * beside it down to nothing. */
html[lang=zh-CN] .home-page .hero-title { font-size: clamp(32px, 4.6vw, 64px); }
html[lang=zh-CN] .home-page .hero-title > span { white-space: nowrap; }

.hero-title > span { display: inline; }
.hero-title > span:last-child { display: block; margin: 0; color: var(--ink); }

/* The one place on this page where Curio orange marks a word. The word itself
 * keeps text.primary so the rule has something to contrast against. */
.creative-emphasis {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--curio);
  text-decoration-thickness: 10px;
  text-underline-offset: 8px;
}

.home-page .hero .creator-word,
.home-page .hero .os-word { color: var(--cyber-ui); }

.hero .eyebrow { margin-bottom: 18px; }

.hero-aside,
html[lang=en] .hero-aside { position: static; width: auto; margin: 42px 0 0; padding: 0; border: 0; }

.home-page .hero-copy { margin: 0 0 42px; max-width: none; font-size: 22px; line-height: 1.85; }

.hero-actions { gap: 16px; flex-wrap: nowrap; }

.hero-actions .button {
  flex: 1;
  min-width: 0;
  max-width: none;
  height: 68px;
  padding: 0 18px;
  border-radius: 12px;
  font-size: 22px;
  font-weight: 650;
  gap: 24px;
  white-space: nowrap;
  outline-color: transparent;
  transition: transform .2s cubic-bezier(.2, .7, .2, 1), box-shadow .2s ease, background-color .2s ease;
}

.home-page .hero-actions .button-primary { background: var(--cyber-ui); color: var(--canvas); }
.button-curio { background: var(--soft-purple); color: var(--cyber-ui); border-color: var(--cyber-ui); }

:root[data-theme=dark] .hero-actions .button-primary { border-color: #A79AF8; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .hero-actions .button-primary { border-color: #A79AF8; }
}

.home-page .hero-art { position: relative; margin: 0; width: 100%; height: auto; }
.hero-art figcaption { margin-top: 20px; text-align: center; font-size: 14px; color: var(--muted); }

/* English sets its own hero measure: a shorter line needs less vertical room
 * and a smaller lead paragraph than the Chinese setting. */
@media (min-width: 761px) {
  html[lang=en] .hero-layout { padding-bottom: 42px; }
  html[lang=en] .hero-copy { font-size: 18px; }
}

@media (max-width: 1100px) {
  .home-page .hero-layout { gap: 36px; }
  .home-page .hero-title { font-size: 5vw; }
  .home-page .hero-copy { font-size: 18px; }
  .hero-actions .button { height: 56px; font-size: 17px; gap: 12px; }
}

@media (max-width: 760px) {
  .home-page .hero-layout { display: block; min-height: 0; padding: 48px 0 54px; }
  .home-page .hero-title,
  html[lang=en] .home-page .hero-title { font-size: clamp(31px, 8.3vw, 56px); }
  .hero-title > span:last-child { display: block; }
  .hero-aside,
  html[lang=en] .hero-aside { margin-top: 30px; }
  .home-page .hero-copy { font-size: 17px; margin-bottom: 30px; }
  .hero-actions { gap: 12px; }
  .hero-actions .button { height: 54px; font-size: 16px; padding: 0 10px; }
  .home-page .hero-art { margin: 42px auto 0; max-width: 490px; }
}

/* Below this width the two actions stack. They stay on the text block's left
 * edge and the filled primary action leads. */
@media (max-width: 420px) {
  html[lang=en] .hero-actions { flex-direction: column; align-items: stretch; }
  /* In a column the main axis is vertical, so flex sizing must not own height. */
  html[lang=en] .hero-actions .button { flex: none; }
  html[lang=en] .hero-actions .button-primary { order: -1; }
  .hero-actions .button { font-size: 14px; }
}

/* ------------------------------------------------------------------ *
 * 6  Concept cards
 *
 * One card per product, used unchanged in the hero and in the products
 * section. Everything inside a card is sized in `cqw` against the scene
 * container, so the same card renders identically wherever it is placed as
 * long as its container is the same width.
 *
 * Each card shows one product doing its actual job. The Curio mark sits on the
 * thing that just happened: the clip AI generated, the live wikilink, the
 * option the agent applied.
 * ------------------------------------------------------------------ */

/* The perspective lives here so all three cards share one vanishing point while
 * still tilting independently — they read as three objects in one space rather
 * than three unrelated planes. */
.card-scene {
  position: relative;
  aspect-ratio: 1;
  isolation: isolate;
  container-type: inline-size;
  perspective: 1000px;
  perspective-origin: 50% 45%;
}

.concept-card {
  position: absolute;
  width: 82%;
  height: 43%;
  padding: 5%;
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 14px 32px #16151c12, 0 3px 8px #16151c0a;
  overflow: hidden;
  transform: translateZ(var(--depth, 0px)) rotate(var(--lean, 0deg));
  transition: transform .7s cubic-bezier(.22, 1, .36, 1), box-shadow .7s ease;
}

.concept-card p { margin: 0; font-size: 2.6cqw; letter-spacing: .03em; opacity: .72; }
.concept-card h3 { margin: 3% 0 0; max-width: 52%; font-size: 5.3cqw; font-weight: 700; line-height: 1.15; letter-spacing: -.055em; }

/* Lean and depth are custom properties so the tilt rule below can rebuild the
 * whole transform without repeating each card's resting position. */
.card-back { top: 4%; right: 3%; --lean: 5deg; --depth: 0px; background: var(--raised); color: var(--text); }
.card-middle {
  top: 30%;
  left: 1%;
  --lean: -5deg;
  --depth: 34px;
  background: var(--soft-purple);
  color: var(--cyber-ui);
  border-color: color-mix(in srgb, var(--cyber-ui) 28%, var(--line));
}
.card-front { top: 55%; right: 1%; --lean: 3deg; --depth: 70px; background: #422cb0; color: #fff; border-color: #5844c1; }
.card-front h3 { font-size: 6.4cqw; }

/* Shared interface block: same position and size on all three cards. */
.card-ui { position: absolute; right: 5%; top: 50%; width: 45%; height: 62%; transform: translateY(-50%); }

/* --- Create: footage, generated material, captions, music and motion, all
   assembled on one timeline. The orange clip is the piece AI made. --- */
.ui-edit { display: flex; align-items: stretch; }
.tracks { display: flex; flex: 1; flex-direction: column; justify-content: center; gap: 7%; }
.tracks span { display: flex; gap: 2.5%; height: 15%; }
.tracks i { border-radius: 2px; background: #ffffff33; }
.tracks span:nth-child(1) i:nth-child(1) { flex: 3; }
.tracks span:nth-child(1) i:nth-child(2) { flex: 5; }
.tracks span:nth-child(1) i:nth-child(3) { flex: 2; }
.tracks span:nth-child(2) i:nth-child(1) { flex: 2; }
.tracks span:nth-child(2) i:nth-child(2) { flex: 4; }
.tracks span:nth-child(2) i:nth-child(3) { flex: 3; }
.tracks span:nth-child(3) i:nth-child(1) { flex: 6; }
.tracks span:nth-child(3) i:nth-child(2) { flex: 3; }
.tracks span:nth-child(4) i { flex: 1; }
.tracks span:nth-child(4) i:nth-child(3) { flex: 4; }
.tracks i.is-made { background: var(--curio); }
.ui-edit .playhead { position: absolute; left: 47%; top: 2%; width: 1.5px; height: 96%; border-radius: 2px; background: #fff; }

/* --- Connect: the note opens inside the assistant, wiki syntax intact --- */
.ui-note { display: flex; flex-direction: column; gap: 8%; }
.ask { display: flex; align-items: center; height: 17%; padding: 0 6%; border: 1px solid currentColor; border-radius: 99px; opacity: .4; }
.ask i { display: block; width: 58%; height: 1cqw; border-radius: 2px; background: currentColor; }
.note { display: flex; flex: 1; flex-direction: column; gap: 10%; padding: 8% 9%; border-radius: 5px; background: var(--raised); color: var(--muted); }
.note b { display: block; width: 52%; height: 1.7cqw; border-radius: 2px; background: currentColor; opacity: .5; }
.note i { display: block; height: 1cqw; border-radius: 2px; background: currentColor; opacity: .24; }
/* The line being written right now: shorter than the settled lines above it,
 * because it has not been finished yet. */
.note i.is-writing { width: 62%; height: 1.4cqw; border-radius: 2px; background: var(--curio); opacity: 1; }

/* --- Customise: an agent working a brand's own configurator --- */
.ui-configure { display: flex; flex-direction: column; gap: 7%; border: 1px solid var(--line); border-radius: 6px; padding: 0 0 7%; overflow: hidden; background: color-mix(in srgb, var(--canvas) 60%, transparent); }
.chrome { display: flex; align-items: center; gap: 3%; height: 15%; padding: 0 5%; border-bottom: 1px solid var(--line); }
.chrome s { display: block; width: 1.6cqw; height: 1.6cqw; border-radius: 50%; background: currentColor; opacity: .22; }
.stage { display: flex; flex: 1; align-items: center; gap: 7%; padding: 0 7%; }
.object { display: grid; flex: 1.1; height: 74%; place-items: center; border-radius: 4px; background: color-mix(in srgb, var(--cyber-ui) 12%, transparent); }
.object u { display: block; width: 58%; height: 42%; border-radius: 3px 3px 8px 3px; background: color-mix(in srgb, var(--cyber-ui) 46%, transparent); }
.swatches { display: flex; flex: .7; flex-direction: column; gap: 14%; }
.swatches i { display: block; width: 2.4cqw; height: 2.4cqw; border-radius: 50%; background: currentColor; opacity: .2; }
.swatches i.is-applied { background: var(--curio); opacity: 1; box-shadow: 0 0 0 .55cqw color-mix(in srgb, var(--curio) 28%, transparent); }
.agent-cursor { position: absolute; right: 24%; bottom: 14%; width: 4.4cqw; height: 4.4cqw; fill: var(--ink); stroke: var(--raised); stroke-width: 1.4; }

/* Each card tilts on its own. The pointer is only ever over one of them, so the
   three respond independently instead of moving as a single sheet; the shared
   perspective on the scene keeps them in one space. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .concept-card {
    transform:
      translateZ(var(--depth, 0px))
      rotateX(calc(var(--tilt-y, 0) * 9deg))
      rotateY(calc(var(--tilt-x, 0) * 12deg))
      rotate(var(--lean, 0deg));
  }
  .concept-card.is-tracking { transition: box-shadow .3s ease; }
  .concept-card:hover { box-shadow: 0 24px 48px #16151c22, 0 8px 16px #16151c14; }
}

/* ------------------------------------------------------------------ *
 * 7  Products
 * ------------------------------------------------------------------ */

.home-page .section { padding: 64px 0 80px; }

.product-list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 36px; margin-top: 50px; border: 0; }
.product-row { display: block; padding: 0; border: 0; }

/* The card is the product's identity here — it already carries the role, the
 * status and the name — so nothing below it repeats them. The container is a
 * square scene exactly like the hero's, clipped to the one card it holds. */
.product-visual {
  position: relative;
  container-type: inline-size;
  aspect-ratio: 1.907;
  margin-bottom: 24px;
  perspective: 900px;
}

/* Same card, laid flat: no lean, no stacking depth. The tilt rule in section 6
 * reads both from custom properties, so it keeps working here unchanged. */
.product-visual .concept-card {
  inset: 0;
  width: 100%;
  height: 100%;
  --lean: 0deg;
  --depth: 0px;
  transition: transform .5s cubic-bezier(.22, 1, .36, 1), box-shadow .5s ease;
}

/* The card's own type scale is tied to the scene width. In the hero the card is
 * 82% of the scene; here it is the whole container, so the scale is corrected
 * by the same ratio and the two render at the same size. */
.product-visual .concept-card p { font-size: 3.2cqw; }
.product-visual .concept-card h3 { font-size: 6.5cqw; }
.product-visual .card-front h3 { font-size: 7.8cqw; }


.product-copy { margin: 0; padding: 0; border: 0; font-size: 17px; line-height: 1.85; }

@media (max-width: 1100px) {
  .product-list { gap: 28px; }
}

@media (max-width: 760px) {
  .home-page .section { padding: 44px 0 54px; }
  .product-list { grid-template-columns: 1fr; gap: 34px; }
}

/* ------------------------------------------------------------------ *
 * 8  Approach
 * ------------------------------------------------------------------ */

.principles { padding: 60px 0 64px; background: var(--canvas); color: var(--ink); }
.principles-layout { display: grid; grid-template-columns: 1fr 1.2fr; gap: 90px; }
.principles .eyebrow { color: var(--cyber-ui); }
.principles h2 { margin-bottom: 60px; max-width: 440px; color: var(--ink); }

/* Numbered, with a Curio bar down the left edge. The three principles used to
 * be separated by hairlines identical to the section boundaries, so they read
 * as more page structure rather than as one list of three; the bar and the
 * numerals mark them as a set without adding a word. The numeral stays --muted
 * because Curio is a pointing colour and carries no text on a light surface. */
.principle-grid { display: block; gap: 48px; counter-reset: principle; }
.principle,
.principle + .principle { min-height: 0; padding: 0 0 0 30px; border: 0; border-left: 2px solid var(--curio); }
.principle + .principle { margin-top: 40px; }
.principle::before {
  counter-increment: principle;
  content: counter(principle, decimal-leading-zero);
  display: block;
  margin-bottom: 12px;
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .12em;
  font-variant-numeric: tabular-nums;
}
.home-page .principle h3 { font-size: 24px; line-height: 1.4; }
.principle p { margin-top: 18px; max-width: none; color: var(--muted); font-size: 17px; line-height: 1.85; }

@media (max-width: 1100px) { .principles-layout { gap: 40px; } }

@media (max-width: 760px) {
  .principles { padding: 44px 0 48px; }
  .principles-layout { grid-template-columns: 1fr; gap: 30px; }
  .principles h2 { margin-bottom: 0; }
  .principle,
  .principle + .principle { padding-left: 22px; border-left: 2px solid var(--curio); }
  .principle + .principle { margin-top: 28px; }
  .principle p { font-size: 16px; }
}

/* ------------------------------------------------------------------ *
 * 9  Content cards — shared by the home page preview and the library directory
 * ------------------------------------------------------------------ */

.card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
.feature-list { margin-top: 40px; }

.card-grid .content-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0;
  min-width: 0;
  min-height: 340px;
  padding: 28px;
  border: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
  border-radius: 14px;
  background: color-mix(in srgb, var(--canvas) 97%, var(--ink));
  color: var(--ink);
  box-shadow: none;
  transition: background .18s ease, border-color .18s ease;
}

.card-grid .content-card[hidden] { display: none; }

/* One entry cannot fill a three-column grid, so it stops pretending to be a
 * grid cell: the lede takes the left, and the article's own section headings —
 * read straight out of library.json, not written for this card — take the
 * right. The renderer switches back to the card grid as soon as there is a
 * second entry, so nothing here has to be undone by hand. */
.card-grid.is-single { grid-template-columns: minmax(0, 1fr); }
.card-grid .content-card.is-feature { flex-direction: row; align-items: stretch; gap: 56px; min-height: 0; padding: 36px 40px; }
.content-card.is-feature .card-lede { display: flex; flex-direction: column; flex: 1 1 58%; min-width: 0; }
.content-card.is-feature .card-meta { justify-content: flex-start; gap: 8px 18px; }
/* The reading time reads as tertiary through position, not through a lighter
 * colour: fading --muted to 82% took 13px text down to 3.56:1 on the card. */
.content-card.is-feature .reading-time { color: var(--muted); }
.card-grid .content-card.is-feature .card-title { margin-bottom: 20px; font-size: 30px; }

.card-outline { flex: 0 0 38%; min-width: 0; padding-left: 40px; border-left: 1px solid color-mix(in srgb, var(--line) 70%, transparent); }
.content-card.is-feature .outline-label { margin: 0 0 18px; font-size: 13px; font-weight: 500; }
.card-outline ol { margin: 0; padding: 0; list-style: none; counter-reset: outline; }
.card-outline li { position: relative; padding-left: 30px; color: var(--ink); font-size: 15px; line-height: 1.6; }
.card-outline li + li { margin-top: 12px; }
.card-outline li::before {
  counter-increment: outline;
  content: counter(outline, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: .15em;
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.card-meta { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 12px; margin-bottom: 22px; font-size: 13px; line-height: 1.5; color: var(--muted); }
.card-meta .topic { font-weight: 500; }
.card-meta time { white-space: nowrap; }

.card-grid .card-title { margin: 0 0 18px; max-width: none; font-size: 25px; font-weight: 550; line-height: 1.45; letter-spacing: -.025em; text-wrap: pretty; }
.card-grid .content-card p { margin: 0 0 28px; font-size: 16px; line-height: 1.75; color: var(--muted); }

.content-card .read-link { margin-top: auto; align-self: flex-start; color: var(--cyber-ui); font-size: 15px; font-weight: 600; text-decoration: none; }
.content-card .arrow { margin-left: 10px; }
.content-card .read-link::after { content: ""; position: absolute; inset: 0; border-radius: 14px; }

.card-grid .content-card:hover,
.card-grid .content-card:focus-within { background: color-mix(in srgb, var(--canvas) 94%, var(--ink)); border-color: var(--line); box-shadow: none; }
.content-card:hover .read-link,
.content-card:focus-within .read-link { text-decoration: underline; text-underline-offset: 5px; }
.content-card:focus-within { outline: 2px solid var(--cyber-ui); outline-offset: 4px; }
.content-card .read-link:focus-visible { outline: none; }

.all-content { display: inline-flex; gap: 12px; margin-top: 22px; padding: 7px 10px; margin-left: -10px; border-radius: 7px; color: var(--cyber-ui); font-size: 16px; font-weight: 650; text-decoration: underline; text-underline-offset: 5px; transition: background .18s ease, color .18s ease; }
.original-language { margin-top: 12px; color: var(--muted); }

.reading .article-body { background: none; }

@media (max-width: 1100px) {
  .card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
  .card-grid .content-card.is-feature { gap: 36px; padding: 32px; }
  .card-outline { flex-basis: 42%; padding-left: 28px; }
}

@media (max-width: 760px) {
  .card-grid { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .feature-list { margin-top: 28px; }
  .card-grid .content-card { min-height: 0; padding: 24px; }
  .card-grid .card-title { font-size: 24px; }
  .card-meta { margin-bottom: 18px; }
  .card-grid .content-card.is-feature { flex-direction: column; gap: 26px; padding: 24px; }
  .card-grid .content-card.is-feature .card-title { font-size: 24px; }
  .card-outline { padding: 24px 0 0; border-left: 0; border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent); }
}

/* ------------------------------------------------------------------ *
 * 10  Contact and account dialogs
 * ------------------------------------------------------------------ */

/* The contact heading deliberately takes the shared .home-page h2 scale. */
.contact-layout { align-items: center; gap: 80px; }
.contact-layout > div:last-child { padding-left: 48px; border-left: 1px solid var(--line); }
.contact-layout > div:last-child > p { font-size: 16px; }

.email-link {
  padding: 6px 8px;
  margin-left: -8px;
  border-bottom: 0;
  border-radius: 8px;
  font-size: 26px;
  font-weight: 500;
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 5px;
  text-decoration-skip-ink: auto;
  transition: background .18s ease, color .18s ease;
}

.social-links { margin-top: 24px; }
.account-triggers { gap: 10px; }
.social-list .account-trigger { width: 44px; height: 44px; flex: 0 0 44px; }
.social-wordmark { font-size: 10px; font-weight: 800; letter-spacing: -.06em; white-space: nowrap; }

html.account-open { overflow: hidden; }

.account-dialog {
  position: fixed;
  inset: auto;
  margin: 0;
  width: min(320px, calc(100vw - 32px));
  max-height: calc(100dvh - 32px);
  padding: 24px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--raised);
  color: var(--ink);
  box-shadow: 0 16px 60px #0002;
  overflow: auto;
  text-align: center;
}

.account-dialog::backdrop { background: #16151c26; }
.account-dialog.account-preview { z-index: 100; transform: none; right: auto; bottom: auto; }
.home-page .account-dialog h3 { margin: 0 28px 6px; font-size: 20px; line-height: 1.4; }
.account-name { margin: 0 0 20px; font-size: 14px; line-height: 1.5; color: var(--muted); }

.account-close {
  position: absolute;
  right: 8px;
  top: 8px;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  font: 28px/1 system-ui;
  cursor: pointer;
}

.account-close:hover { background: var(--soft-purple); color: var(--cyber-ui); }
.account-qr { display: block; width: 100%; height: auto; aspect-ratio: 1; object-fit: contain; background: #fff; border-radius: 4px; }

.account-visit {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  margin-top: 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--cyber-ui);
  font-size: 14px;
  font-weight: 650;
  text-decoration: none;
}

.account-visit:hover { background: var(--soft-purple); }

@media (max-width: 1100px) { .contact-layout { gap: 28px; } }

@media (max-width: 760px) {
  .contact-layout { gap: 28px; }
  .contact-layout > div:last-child { padding: 0; border: 0; }
  .email-link { font-size: 23px; }
  .account-dialog { inset: 50% auto auto 50%; transform: translate(-50%, -50%); }
}

/* ------------------------------------------------------------------ *
 * 11  Footer
 * ------------------------------------------------------------------ */

.site-footer { padding: 32px 0; }

@media (max-width: 760px) { .footer-row { font-size: 13px; } }

/* ------------------------------------------------------------------ *
 * 12  Interaction vocabulary
 *
 * One rule for every interactive surface: a filled target on hover and focus,
 * a visible focus ring, no motion that the arrow has to chase.
 * ------------------------------------------------------------------ */

a, button, summary { touch-action: manipulation; }
a:focus-visible, button:focus-visible, summary:focus-visible { outline: 3px solid var(--cyber-ui); outline-offset: 4px; border-radius: 6px; }

.nav-links > a:hover, .nav-links > a:focus-visible,
.nav > a:hover, .nav > a:focus-visible,
.nav-social a:hover, .nav-social a:focus-visible,
.nav summary:hover, .nav summary:focus-visible,
.nav button:hover, .nav button:focus-visible { background: #422CB0; color: #fff; box-shadow: none; transform: none; text-decoration: none; }

.nav summary:hover img, .nav summary:focus-visible img,
.nav button:hover img, .nav button:focus-visible img { filter: brightness(0) invert(1); }

.hero-actions .button:hover,
.hero-actions .button:focus-visible {
  transform: translateY(-3px);
  filter: none;
  box-shadow: inset 0 1px 0 #ffffff30, 0 5px 10px #16151c14, 0 12px 24px #16151c24;
}

.hero-actions .button-primary:hover,
.hero-actions .button-primary:focus-visible { background: #4933BA; color: #fff; border-color: #4933BA; }

.home-page .hero-actions .button-curio:hover,
.home-page .hero-actions .button-curio:focus-visible { background: var(--soft-purple); color: var(--cyber-ui); border-color: var(--cyber-ui); }

.hero-actions .button:focus-visible { outline: 3px solid var(--cyber-ui); outline-offset: 4px; }
.hero-actions .button:active { transform: translateY(0) scale(.98); box-shadow: inset 0 1px 2px #16151c18, 0 2px 5px #16151c14; }

/* The arrow belongs to the button and travels with it. */
.hero-actions .button span { display: inline-block; transform: none; transition: none; }

.all-content:hover, .all-content:focus-visible,
.email-link:hover, .email-link:focus-visible,
.social-list a:hover, .social-list a:focus-visible { background: #422CB0; color: #fff; transform: none; box-shadow: none; text-decoration: none; }

.all-content span { display: inline-block; transition: transform .18s ease; }
.all-content:hover span { transform: translateX(4px); }
.email-link:hover, .email-link:focus-visible { text-decoration-thickness: 1px; }

.social-list a[data-platform="YouTube"]:hover path,
.social-list a[data-platform="YouTube"]:focus-visible path { fill: #422CB0; }
.nav-social a[data-platform="YouTube"]:hover path,
.nav-social a[data-platform="YouTube"]:focus-visible path { fill: #422CB0; }

.account-trigger:focus-visible, .account-close:focus-visible, .account-visit:focus-visible { outline: 2px solid var(--cyber-ui); outline-offset: 3px; }

.filters button { transition: background .18s ease, color .18s ease, box-shadow .18s ease; }
.filters button:hover { background: color-mix(in srgb, var(--cyber-ui) 18%, var(--canvas)); box-shadow: 0 0 0 2px var(--cyber-ui); }
.filters button[aria-pressed=true]:hover { background: var(--cyber); color: #fff; }

.back-link:hover,
.site-footer a:hover { color: var(--cyber-ui); text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 5px; }

/* ------------------------------------------------------------------ *
 * 13  Motion
 * ------------------------------------------------------------------ */

/* The `transition` shorthand resets transition-delay, so every stagger rule
 * must come after it. */
.js .reveal { transform: translateY(24px); transition: opacity .75s ease, transform .85s cubic-bezier(.2, .7, .2, 1); }
.js .reveal.is-visible { transform: translateY(0); }

/* Related items in a row enter together with a light lead. */
.product-row.reveal:nth-child(2), .principle.reveal:nth-child(2) { transition-delay: .1s; }
.product-row.reveal:nth-child(3), .principle.reveal:nth-child(3) { transition-delay: .2s; }

/* The cards drop in and settle past their resting point before coming back —
 * the overshoot is what makes them read as objects with weight. */
.creative-scene.is-visible .concept-card { animation: card-drop 780ms cubic-bezier(.34, 1.48, .5, 1) both; }
.creative-scene.is-visible .card-middle { animation-delay: 110ms; }
.creative-scene.is-visible .card-front { animation-delay: 220ms; }

@keyframes card-drop {
  from { opacity: 0; translate: 0 38px; scale: .93; }
  to { opacity: 1; translate: 0 0; scale: 1; }
}

/* Returning through history restores the page as it was, without replaying. */
.history-return .reveal,
.history-return .creative-scene.is-visible .concept-card { transition: none !important; animation: none !important; }

@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: 180ms; animation-timing-function: ease-out; }
  .content-card .arrow { display: inline-block; transition: transform .18s ease; }
  .content-card:hover .arrow, .content-card:focus-within .arrow { transform: translateX(3px); }
  .account-dialog[open] { animation: account-appear .15s ease-out; }
  @keyframes account-appear { from { opacity: 0; } to { opacity: 1; } }
}

@media (max-width: 760px) {
  /* Stacked on one column, a stagger just delays the content. */
  .product-row.reveal, .principle.reveal { transition-delay: 0s; }
}

@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; transition: none; }
  .concept-card { transition: none; }
  .creative-scene.is-visible .concept-card { animation: none; }
  .site-header .header-content { transition: none; }
  .card-grid .content-card { transition: none; }
  .hero-actions .button { transition: none; }
  .hero-actions .button:hover,
  .hero-actions .button:focus-visible,
  .hero-actions .button:active { transform: none; }
  .nav-social a:hover, .social-list a:hover { transform: none; }
}
