/* ==========================================================================
   Robright — style.css
   ========================================================================== */

/* Pretendard Variable comes from assets/fonts/pretendard/pretendardvariable-dynamic-subset.css, linked before
   this file on every page: the font split by character range, so a page downloads only what it shows. */


:root {
  --blue: #0123B4;
  --blue-deep: #001A87;
  --blue-tint: #E9EDFB;
  --blue-line: #B7C2EE;
  --blue-soft: #7A8CE0;
  --night: #0A0F2C;
  --night-line: rgba(255, 255, 255, .14);
  --ink: #12162B;
  --graphite: #3B4157;
  --mute: #666D82;
  --line: #DCE0E8;
  --steel: #EEF1F5;
  --paper: #FFFFFF;
  --scan: #4FD8FF;
  --icon-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4.5 12.5l5 5L19.5 7' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");

  --font: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", "Malgun Gothic", system-ui, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Consolas, monospace;
  --header-h: 72px;
  --gutter: 20px;
  --radius: 6px;
  --ease: cubic-bezier(.2, .7, .2, 1);
  --section-y: clamp(96px, 12vw, 168px);
  --block-gap: clamp(88px, 10vw, 152px);
}

@media (min-width: 768px) { :root { --gutter: 40px; } }
@media (max-width: 899px) { :root { --header-h: 60px; } }

/* ---------- Base ---------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: var(--header-h);
}
html:not(.lenis) { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.7;
  color: var(--ink);
  background: var(--paper);
  word-break: keep-all;
  overflow-wrap: break-word;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
@media (min-width: 1024px) { body { font-size: 17px; } }

h1, h2, h3, h4 { text-wrap: balance; }
img, svg, video { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
ul, ol { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4, p, figure, dl, dd, blockquote { margin: 0; }
table { border-collapse: collapse; }

:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; border-radius: 2px; }
::selection { background: var(--blue); color: #fff; }
.section--contact :focus-visible, .site-footer :focus-visible, .hero :focus-visible, .vision :focus-visible,
.site-header:not(.is-solid) :focus-visible, .menu-open .site-header :focus-visible { outline-color: #fff; }
/* Sections focused after an in-page link: the scroll already shows where you are. */
section[tabindex="-1"]:focus, main[tabindex="-1"]:focus { outline: none; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: fixed; left: 12px; top: -60px; z-index: 100;
  padding: 10px 16px; border-radius: var(--radius);
  background: var(--ink); color: #fff; font-weight: 600;
}
.skip-link:focus { top: 12px; }

.container {
  width: 100%;
  max-width: calc(1280px + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}


/* Lenis */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5em;
  height: 48px; padding: 0 24px;
  border-radius: 999px; border: 1px solid transparent;
  font-size: 15px; font-weight: 600; letter-spacing: -.01em; white-space: nowrap;
  transition: background-color .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease);
}
.btn--primary { background: var(--blue); color: #fff; }
.btn--primary:hover { background: var(--blue-deep); }
.btn--light { background: #fff; color: var(--ink); }
.btn--light:hover { background: var(--blue); color: #fff; }
.btn--outline-light { border-color: rgba(255, 255, 255, .45); color: #fff; }
.btn--outline-light:hover { border-color: #fff; background: rgba(255, 255, 255, .1); }

/* ---------- Header ---------- */

.site-header {
  position: fixed; inset: 0 0 auto; z-index: 50;
  height: var(--header-h);
  color: #fff;
  transition: background-color .3s var(--ease), color .3s var(--ease), box-shadow .3s var(--ease);
}
.site-header.is-solid {
  background: rgba(255, 255, 255, .97);
  color: var(--ink);
  box-shadow: 0 1px 0 var(--line);
}
.header-inner {
  height: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
}
.brand { position: relative; z-index: 2; display: block; width: 116px; aspect-ratio: 640 / 248; }
@media (min-width: 900px) { .brand { width: 128px; } }
.brand-logo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; transition: opacity .3s var(--ease); }
.brand-logo--blue { opacity: 0; }
.is-solid .brand-logo--blue { opacity: 1; }
.is-solid .brand-logo--white { opacity: 0; }

.nav { display: flex; align-items: center; gap: 40px; }
.nav-list { display: flex; gap: 36px; }
.nav-list a { position: relative; display: block; padding: 8px 0; font-size: 15px; font-weight: 500; }
.nav-list a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 3px; height: 1.5px;
  background: currentColor; transform: scaleX(0); transform-origin: left;
  transition: transform .3s var(--ease);
}
.nav-list a:hover::after, .nav-list a.is-active::after { transform: scaleX(1); }
.nav-cta { height: 40px; padding: 0 20px; font-size: 14px; }
/* Over the hero video (transparent header) Contact is a white outline like the menu text around it;
   it turns solid blue with the rest of the header once the page scrolls. */
@media (min-width: 900px) {
  .site-header:not(.is-solid) .nav-cta { background: transparent; border-color: rgba(255, 255, 255, .6); color: #fff; }
  .site-header:not(.is-solid) .nav-cta:hover { background: rgba(255, 255, 255, .12); border-color: #fff; }
}

.menu-toggle { display: none; }

@media (max-width: 899px) {
  .menu-toggle {
    position: relative; z-index: 2;
    display: flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; margin-right: -10px;
  }
  .menu-toggle-bars { position: relative; width: 22px; height: 12px; }
  .menu-toggle-bars i {
    position: absolute; left: 0; width: 100%; height: 1.75px; background: currentColor;
    transition: transform .3s var(--ease), top .3s var(--ease);
  }
  .menu-toggle-bars i:first-child { top: 0; }
  .menu-toggle-bars i:last-child { top: 10px; }
  .menu-toggle[aria-expanded="true"] .menu-toggle-bars i:first-child { top: 5px; transform: rotate(45deg); }
  .menu-toggle[aria-expanded="true"] .menu-toggle-bars i:last-child { top: 5px; transform: rotate(-45deg); }

  /* The menu is indented from the screen edge, and Contact follows the list as one more link
     (same type, same 4px rhythm) rather than a button. */
  .nav {
    position: fixed; inset: 0; z-index: 1;
    flex-direction: column; align-items: flex-start;
    justify-content: center; justify-content: safe center;
    gap: 4px;
    overflow-y: auto; overscroll-behavior: contain;
    padding: var(--header-h) var(--gutter) 32px clamp(48px, 16vw, 120px);
    background: var(--night); color: #fff;
    opacity: 0; visibility: hidden;
    transition: opacity .3s var(--ease), visibility 0s linear .3s;
  }
  .menu-open .nav { opacity: 1; visibility: visible; transition: opacity .3s var(--ease); }
  .nav-list { flex-direction: column; gap: 4px; }
  .nav-list a, .nav-cta { padding: 6px 0; font-size: clamp(24px, min(9vw, 6.5vh), 44px); font-weight: 650; letter-spacing: -.03em; }
  .nav-list a::after { display: none; }
  .nav-cta, .nav-cta:hover { display: block; height: auto; border: 0; border-radius: 0; background: none; color: inherit; }
  .nav-list a.is-active, .nav-cta.is-active { color: var(--scan); }

  .menu-open { overflow: hidden; }
  .menu-open .site-header { color: #fff; background: transparent; box-shadow: none; }
  .menu-open .brand-logo--white { opacity: 1; }
  .menu-open .brand-logo--blue { opacity: 0; }
}

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

.hero {
  position: relative; isolation: isolate; overflow: hidden;
  display: flex; align-items: flex-end;
  min-height: 100vh; min-height: 100svh;
  color: #fff; background: var(--night);
}
.hero-media, .hero-video { position: absolute; inset: 0; width: 100%; height: 100%; }
.hero-video { object-fit: cover; }
/* The poster is set by the script after the video; without JavaScript it shows here instead. */
html:not(.js) .hero-media { background: url("../img/poster.jpg") center / cover; }
.hero-shade {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(10, 15, 44, .55) 0%, rgba(10, 15, 44, 0) 22%, rgba(10, 15, 44, 0) 42%, rgba(10, 15, 44, .85) 100%),
    linear-gradient(90deg, rgba(10, 15, 44, .5) 0%, rgba(10, 15, 44, 0) 65%);
}
.hero-content {
  --hero-title-size: clamp(2.6rem, 6.6vw, 6.25rem);
  position: relative; z-index: 1;
  padding-top: calc(var(--header-h) + 48px);
  padding-bottom: clamp(64px, 11vh, 120px);
}
.hero-title {
  font-size: var(--hero-title-size);
  font-weight: 700; line-height: 1.1; letter-spacing: -.04em;
}
/* Desktop: grows more slowly from 1024px (where it meets 6.6vw, so no jump) — about 76px at 1280, at most 88px. */
@media (min-width: 1024px) { .hero-content { --hero-title-size: min(calc(3.3vw + 34px), 5.5rem); } }
.hero-line { display: block; overflow: hidden; padding-bottom: .06em; }
.hero-line > span { display: block; animation: hero-rise 1.1s var(--ease) .15s both; }
.hero-line + .hero-line > span { animation-delay: .27s; }
.hero-sub {
  margin-top: clamp(20px, 2.4vw, 32px); max-width: 36em;
  font-size: clamp(1.0625rem, 1.5vw, 1.3rem); line-height: 1.6;
  color: rgba(255, 255, 255, .86);
  animation: hero-fade .9s var(--ease) .6s both;
}
.hero-actions {
  margin-top: clamp(28px, 3.2vw, 44px);
  display: flex; flex-wrap: wrap; gap: 12px;
  animation: hero-fade .9s var(--ease) .75s both;
}
.hero-scan {
  position: absolute; top: 0; bottom: 0; left: -2px; z-index: 1; width: 1px;
  background: var(--scan);
  box-shadow: 0 0 16px 2px rgba(79, 216, 255, .55);
  opacity: 0;
  animation: hero-scan 2.4s cubic-bezier(.45, 0, .2, 1) .35s 1 both;
}
@keyframes hero-rise { from { transform: translateY(105%); } to { transform: none; } }
@keyframes hero-fade { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes hero-scan {
  0% { transform: translateX(0); opacity: 0; }
  8% { opacity: .9; }
  80% { opacity: .7; }
  100% { transform: translateX(calc(100vw + 4px)); opacity: 0; }
}

.video-toggle {
  position: absolute; z-index: 2;
  right: max(var(--gutter), calc((100vw - 1280px) / 2));
  bottom: clamp(64px, 11vh, 120px);
  display: grid; place-items: center;
  width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .4); color: #fff;
  transition: border-color .25s var(--ease), background-color .25s var(--ease);
}
.video-toggle[hidden] { display: none; }
.video-toggle:hover { border-color: #fff; background: rgba(255, 255, 255, .1); }
.video-toggle svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.video-toggle .icon-play { display: none; fill: currentColor; }
.video-toggle[aria-pressed="true"] .icon-play { display: block; }
.video-toggle[aria-pressed="true"] .icon-pause { display: none; }
@media (max-width: 639px) { .video-toggle { bottom: 20px; } }

/* ---------- Sections ---------- */

.section { padding-block: var(--section-y); }
.section--solution, .section--news { background: var(--steel); }
.section--solution { padding-bottom: 0; }
.section--contact { background: var(--night); color: #fff; }

.section-head { display: grid; gap: 20px; margin-bottom: clamp(48px, 6vw, 88px); }
@media (min-width: 1024px) {
  .section-head { grid-template-columns: 7fr 5fr; align-items: end; gap: 56px; }
}
.section-title {
  font-size: clamp(2rem, 4.3vw, 3.5rem);
  font-weight: 700; line-height: 1.22; letter-spacing: -.035em;
}
.section-title br { display: none; }
@media (min-width: 640px) { .section-title br { display: inline; } }
.section-lead {
  max-width: 34em;
  font-size: clamp(1.0625rem, 1.35vw, 1.2rem); line-height: 1.7;
  color: var(--graphite);
}
.section--contact .section-lead { color: rgba(255, 255, 255, .72); }
/* Contact heading: the key phrases keep the usual section-title size, the words around them drop to 3/4,
   so the phrases stand out by scale alone. */
.section--contact .section-title { font-size: calc(clamp(2rem, 4.3vw, 3.5rem) * .75); }
.section--contact .section-title strong { font-size: 1.3333em; font-weight: inherit; }
@media (min-width: 1024px) {
  .section--contact .section-head { grid-template-columns: minmax(0, 1fr); gap: 24px; }
}

.block-title {
  font-size: clamp(1.5rem, 2.4vw, 2.125rem);
  font-weight: 700; line-height: 1.3; letter-spacing: -.03em;
}
.block-text { margin-top: 12px; max-width: 36em; color: var(--graphite); }

/* ---------- Problem ---------- */

.pain-list { display: grid; border-top: 1px solid var(--line); }
.pain { padding: 36px 0 40px; border-bottom: 1px solid var(--line); }
/* Three across from 1024px (narrower, the two-line titles would wrap again); a little tighter until 1200px. */
@media (min-width: 1024px) {
  .pain-list { grid-template-columns: repeat(3, minmax(0, 1fr)); border-bottom: 1px solid var(--line); }
  .pain { padding: 48px 36px 44px; border-bottom: 0; border-left: 1px solid var(--line); }
  .pain:first-child { padding-left: 0; border-left: 0; }
  .pain:last-child { padding-right: 0; }
}
@media (min-width: 1024px) and (max-width: 1199px) { .pain { padding-inline: 26px; } }
.pain-ill { display: flex; justify-content: center; height: 140px; margin-bottom: 28px; color: var(--ink); }
.ill { width: auto; height: 100%; max-width: 100%; overflow: visible; }
.ill-line { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.ill-faint { opacity: .35; }
.ill-accent { fill: var(--blue-tint); stroke: var(--blue); stroke-width: 2; stroke-linejoin: round; }
.ill-warn { fill: none; stroke: var(--ink); stroke-width: 2; stroke-linecap: round; opacity: .7; }
.ill-spray { fill: none; stroke: var(--blue); stroke-width: 1.75; stroke-linecap: round; stroke-dasharray: 3 6; }
.ill-dirt circle { fill: var(--ink); opacity: .28; }
/* Mechanical wash brushes: bristles hang from the axle at rest and fan out (centrifugal) while spinning
   while the card is in view (.is-active, set by main.js) or hovered. */
.ill-axle { fill: none; stroke: var(--blue); stroke-width: 2; stroke-linecap: round; }
.ill-hub { fill: var(--paper); stroke: var(--blue); stroke-width: 2; }
.ill-hair {
  fill: none; stroke: var(--blue); stroke-width: 2.2; stroke-linecap: round;
  transform: rotate(var(--a));
  transition: transform .6s cubic-bezier(.2, .8, .2, 1);
}
.ill-tier:nth-of-type(even) .ill-hair { stroke: var(--blue-soft); }
/* --a: hanging angle, --A: spun-out angle (positive = towards the left), --d: phase in the 1.6s turn.
   A right-pointing bristle equals a left-pointing one half a turn (.8s) later, so the ten phases land
   1/10 turn apart: left 0, .32, .64, .96, 1.28 and right (+.8) .16, .48, .8, 1.12, 1.44. */
.ill-tier > :nth-child(1) { --a: 4deg; --A: 58deg; --d: 0s; }
.ill-tier > :nth-child(2) { --a: 10deg; --A: 66deg; --d: -.32s; }
.ill-tier > :nth-child(3) { --a: 16deg; --A: 74deg; --d: -.64s; }
.ill-tier > :nth-child(4) { --a: 22deg; --A: 82deg; --d: -.96s; }
.ill-tier > :nth-child(5) { --a: 28deg; --A: 90deg; --d: -1.28s; }
.ill-tier > :nth-child(6) { --a: -4deg; --A: -58deg; --d: -.96s; }
.ill-tier > :nth-child(7) { --a: -10deg; --A: -66deg; --d: -1.28s; }
.ill-tier > :nth-child(8) { --a: -16deg; --A: -74deg; --d: 0s; }
.ill-tier > :nth-child(9) { --a: -22deg; --A: -82deg; --d: -.32s; }
.ill-tier > :nth-child(10) { --a: -28deg; --A: -90deg; --d: -.64s; }
.pain.is-active .ill-hair { transform: rotate(var(--A)); }
@media (hover: hover) {
  .pain:hover .ill-hair { transform: rotate(var(--A)); }
}
.ill-mitt { transition: transform .5s var(--ease); }

.pain-method { margin-bottom: 10px; font-size: 14px; font-weight: 600; color: var(--blue); }
.pain-title {
  font-size: clamp(1.375rem, 1.9vw, 1.625rem);
  font-weight: 700; line-height: 1.38; letter-spacing: -.025em;
}
.pain-desc { margin-top: 14px; color: var(--graphite); }

@media (prefers-reduced-motion: no-preference) {
  .pain.is-active .ill-mitt { animation: ill-wipe 1.4s var(--ease) infinite; }
  .pain.is-active .ill-spin { animation: hair-spin .8s ease-in-out var(--d, 0s) infinite alternate; }
  .pain.is-active .ill-brush--r .ill-spin { animation-direction: alternate-reverse; }
  .pain.is-active .ill-spray { animation: ill-spray .5s linear infinite; }
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .pain:hover .ill-mitt { animation: ill-wipe 1.4s var(--ease) infinite; }
  .pain:hover .ill-spin { animation: hair-spin .8s ease-in-out var(--d, 0s) infinite alternate; }
  .pain:hover .ill-brush--r .ill-spin { animation-direction: alternate-reverse; }
  .pain:hover .ill-spray { animation: ill-spray .5s linear infinite; }
}
@keyframes ill-wipe { 0%, 100% { transform: translateX(-26px); } 50% { transform: translateX(30px); } }
/* A fanned-out bristle swinging around the axle, seen from the front: its width runs +1 → 0 → −1 like a cosine. */
@keyframes hair-spin { from { transform: scaleX(1); } to { transform: scaleX(-1); } }
@keyframes ill-spray { to { stroke-dashoffset: -18; } }

.voices { margin-top: clamp(56px, 7vw, 96px); }
/* Reviews as speech bubbles: stacked and alternating sides like a conversation; from 900px three across
   and two below, staggered, overlapping only across the rows. Bubbles overlap as far as each other's quote marks and padding, never their
   words, and each paints above the next so every tail shows. Quote marks open top-left and close
   bottom-right, text centered. */
/* Rows share one height (1fr), so every bubble is as tall as the tallest; overlaps are drawn with
   translate rather than negative margins, which would stretch the bubbles. */
/* isolation: the bubbles' stacking order stays inside the list, so they never paint over the 'Shape' blur. */
.voice-list { display: grid; grid-auto-rows: 1fr; isolation: isolate; }
.voice-list li {
  position: relative;
  display: flex; flex-direction: column;
  padding: clamp(22px, 2.4vw, 30px) clamp(24px, 2.6vw, 34px) clamp(14px, 1.6vw, 20px);
  border: 1px solid var(--blue-line);
  border-radius: 14px;
  background: var(--paper);
  text-wrap: balance;
}
.voice-list li::after {
  content: "";
  position: absolute; left: 40px; bottom: -8px;
  width: 14px; height: 14px;
  border-right: 1px solid var(--blue-line); border-bottom: 1px solid var(--blue-line);
  background: var(--paper);
  transform: rotate(45deg);
}
.voice-list li:nth-child(3)::after,
.voice-list li:nth-child(5)::after { left: auto; right: 40px; }
/* Each bubble paints above the next so its tail shows; on desktop the last sits on top of the second. */
.voice-list li:nth-child(1) { z-index: 6; }
.voice-list li:nth-child(2) { z-index: 4; }
.voice-list li:nth-child(3) { z-index: 3; }
.voice-list li:nth-child(4) { z-index: 2; }
.voice-list li:nth-child(5) { z-index: 1; }
@media (max-width: 899px) {
  /* Compact bubbles: tighter padding, smaller marks and leading keep the stack short to scroll. */
  .voice-list li { width: fit-content; max-width: 78%; padding: 14px 20px 10px; }
  .voice-list { margin-bottom: -32px; }
  .voice-list li:nth-child(2) { translate: 0 -8px; }
  .voice-list li:nth-child(3) { translate: 0 -16px; }
  .voice-list li:nth-child(4) { translate: 0 -24px; }
  .voice-list li:nth-child(5) { translate: 0 -32px; }
  .voice-list li:nth-child(even) { margin-left: auto; }
  /* Stacked, each tail points to the side its bubble sits on. */
  .voice-list li:nth-child(odd)::after { left: 40px; right: auto; }
  .voice-list li:nth-child(even)::after { left: auto; right: 40px; }
  /* (.voice-list li q: the base q rules come later in the file, so these need the extra weight.) */
  .voice-list li q { gap: 0; line-height: 1.5; }
  .voice-list li q::before, .voice-list li q::after { height: 16px; font-size: 32px; }
}
@media (min-width: 900px) {
  /* Each bubble is as wide as its text needs: two medium reviews and the short one above, two long ones below. */
  .voice-list { grid-template-columns: repeat(24, minmax(0, 1fr)); padding-bottom: 12px; }
  /* Neighbours in a row keep a 16px gap; bubbles overlap only across the rows, each on one face. */
  .voice-list li { margin-inline: 8px; }
  .voice-list li:nth-child(1) { grid-column: 1 / span 8; margin-left: 0; }
  .voice-list li:nth-child(2) { grid-column: 9 / span 8; }
  .voice-list li:nth-child(3) { grid-column: 17 / span 7; }
  .voice-list li:nth-child(4) { grid-column: 3 / span 11; }
  .voice-list li:nth-child(5) { grid-column: 14 / span 11; margin-right: 0; }
  .voice-list li:nth-child(2) { translate: 0 12px; }
  .voice-list li:nth-child(4) { translate: 0 -12px; }
  .voice-list li:nth-child(5) { z-index: 5; }
  /* The short bubble floats a little above the row, clear of the bubble below it, and tucks under its
     left neighbour (24px in, past the 8px gap margin). */
  .voice-list li:nth-child(3) { translate: 0 -16px; margin-left: -24px; }
}
/* With room to spare, the lower bubbles narrow toward their balanced lines; narrower desktops keep them
   wider so long reviews stay on two lines. */
@media (min-width: 1200px) {
  .voice-list li:nth-child(4) { grid-column: 4 / span 9; }
  .voice-list li:nth-child(5) { grid-column: 13 / span 9; margin-right: 8px; }
}
.voice-list q {
  flex: 1; display: flex; flex-direction: column; gap: 6px;
  quotes: "\201C" "\201D";
  font-size: clamp(1.125rem, 1.5vw, 1.3125rem); font-weight: 500;
  line-height: 1.6; letter-spacing: -.02em; color: var(--ink);
  text-align: center;
}
.voice-list q::before,
.voice-list q::after {
  display: block; height: 22px;
  font: 700 42px/1 Georgia, "Times New Roman", serif;
  letter-spacing: 0; color: var(--blue-soft);
}
/* The marks hug the bubble's corners, which keeps the text centered between them
   and the marks level across the desktop row. */
.voice-list q::before { content: open-quote; margin-bottom: auto; text-align: left; }
.voice-list q::after { content: close-quote; margin-top: auto; text-align: right; }
.voices figcaption { margin-top: 32px; font-size: 14px; color: var(--mute); text-align: right; }

/* What drivers want, as a diagram: one hub ("운전자가 원하는 세차") and the four wants.
   The hub in the middle, two wants on each side, each side's pair joined by a bracket whose middle meets the
   hub; the left-hand wants are mirrored so both sides' icons face it. The same on every screen, scaled down
   (hub, reach and gaps follow the width); on phones each want stacks its icon over its words. */
.wants { margin-top: var(--block-gap); }
.wants-title {
  margin-bottom: clamp(40px, 6vw, 80px);
  font-size: clamp(1.25rem, 2.1vw, 1.75rem); font-weight: 700; line-height: 1.38; letter-spacing: -.03em;
  text-align: center;
}
/* The four qualities that could not coexist stand out in brand blue (the title is already bold). */
.wants-title strong { font-weight: inherit; color: var(--blue); }
/* On a narrow screen the closing clause wraps as one piece rather than splitting mid-phrase. */
.wants-title-end { display: inline-block; }
.wants-map {
  --wants-line: 2px;
  --wants-hub: clamp(92px, 26vw, 220px);  /* the hub circle's width */
  --wants-reach: clamp(8px, 2.5vw, 32px); /* half the column gap: where each side's bracket stands */
  --wants-row-gap: clamp(10px, 2vw, 20px);
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--wants-hub) minmax(0, 1fr);
  grid-auto-rows: 1fr; column-gap: calc(var(--wants-reach) * 2); row-gap: var(--wants-row-gap);
  max-width: 960px; margin-inline: auto;
}
.wants-list { display: contents; }
.wants-hub {
  position: relative;
  grid-column: 2; grid-row: 1 / span 2; align-self: center; justify-self: center;
  display: flex; align-items: center; justify-content: center;
  width: var(--wants-hub); height: var(--wants-hub); border-radius: 50%;
  background: var(--blue); color: #fff; box-shadow: 0 0 0 clamp(6px, 1.2vw, 12px) var(--blue-tint);
  font-size: clamp(.9375rem, 2.6vw, 1.625rem); font-weight: 700; line-height: 1.35; letter-spacing: -.02em; text-align: center;
}
.wants-hub::before, .wants-hub::after {
  content: ""; position: absolute; top: 50%; width: var(--wants-reach); height: var(--wants-line); margin-top: -1px;
  background: var(--blue-line);
}
.wants-hub::before { right: 100%; }
.wants-hub::after { left: 100%; }
.wants-node {
  position: relative;
  display: flex; align-items: center; gap: 16px;
  padding: 22px 26px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--paper);
  font-size: clamp(1.0625rem, 1.5vw, 1.25rem); font-weight: 650; line-height: 1.38; letter-spacing: -.02em;
}
.wants-node:nth-child(1) { grid-column: 1; grid-row: 1; }
.wants-node:nth-child(2) { grid-column: 1; grid-row: 2; }
.wants-node:nth-child(3) { grid-column: 3; grid-row: 1; }
.wants-node:nth-child(4) { grid-column: 3; grid-row: 2; }
.wants-node:nth-child(-n+2) { flex-direction: row-reverse; text-align: right; }
.wants-icon {
  flex: none; width: 44px; height: 44px; padding: 9px;
  border-radius: 50%; background: var(--blue-tint);
  fill: none; stroke: var(--blue); stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round;
}
/* Bracket: a tick out of each want toward the hub, and an upright joining the pair across the row gap. */
.wants-node::before, .wants-node::after { content: ""; position: absolute; background: var(--blue-line); }
.wants-node::before { top: 50%; width: var(--wants-reach); height: var(--wants-line); margin-top: -1px; }
.wants-node:nth-child(-n+2)::before { left: 100%; }
.wants-node:nth-child(n+3)::before { right: 100%; }
/* Offsets count from inside the 1px border, so the uprights stand exactly var(--wants-reach) out; each runs
   half the row gap past its want (plus the border) to meet its partner's. */
.wants-node::after { width: var(--wants-line); }
.wants-node:nth-child(-n+2)::after { left: calc(100% + var(--wants-reach)); }
.wants-node:nth-child(n+3)::after { left: calc(-1 * var(--wants-reach) - 2px); }
.wants-node:nth-child(odd)::after { top: 50%; bottom: calc(-1px - var(--wants-row-gap) / 2); }
.wants-node:nth-child(even)::after { top: calc(-1px - var(--wants-row-gap) / 2); bottom: 50%; }
/* Phones: too narrow for icon and words side by side, so each want stacks them, centred; lines break only
   between words. */
@media (max-width: 639px) {
  .wants-node, .wants-node:nth-child(-n+2) {
    flex-direction: column; justify-content: center; gap: 8px;
    padding: 14px 6px; text-align: center; word-break: keep-all;
    font-size: .875rem;
  }
  .wants-icon { width: 36px; height: 36px; padding: 7px; }
}
/* The solution intro block ('로브라이트는 손 세차의 방식을 자동화합니다'): it closes the Intro section, and the
   Solution menu lands on it. (The Solution section's own cards are .solution-card, below.) */
.solution-intro { margin-top: var(--block-gap); display: grid; gap: 40px; align-items: center; }
@media (min-width: 900px) { .solution-intro { grid-template-columns: 5fr 6fr; gap: 72px; } }
.solution-intro-media { overflow: hidden; aspect-ratio: 4 / 3; border-radius: var(--radius); background: var(--night); }
@media (min-width: 900px) { .solution-intro-media { aspect-ratio: 4 / 5; } }
.solution-intro-media img { width: 100%; height: 100%; object-fit: cover; }
.solution-intro-title { font-size: clamp(1.75rem, 3vw, 2.5rem); font-weight: 700; line-height: 1.3; letter-spacing: -.035em; }
.solution-intro-title br { display: none; }
@media (min-width: 640px) { .solution-intro-title br { display: inline; } }
.solution-intro-text { margin-top: 20px; max-width: 34em; color: var(--graphite); }
.solution-intro-points { margin-top: 36px; border-top: 1px solid var(--line); }
.solution-intro-points > div { display: grid; gap: 4px; padding: 20px 0; border-bottom: 1px solid var(--line); }
@media (min-width: 640px) { .solution-intro-points > div { grid-template-columns: 190px 1fr; gap: 24px; align-items: center; } }
.solution-intro-points dt { font-weight: 650; }
.solution-intro-points dd { color: var(--graphite); }

/* ---------- Solution: the three cards ---------- */

.solution-cards { display: grid; gap: clamp(56px, 7vw, 104px); }
.solution-card { display: grid; grid-template-columns: minmax(0, 1fr); gap: 28px; align-items: center; }
@media (min-width: 900px) {
  .solution-card { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 72px; }
  .solution-card:nth-child(even) .solution-card-media { order: -1; }
  /* The process card runs full width: its text above, the eight steps in one row below. */
  .solution-card--process { grid-template-columns: minmax(0, 1fr); row-gap: 40px; }
  .solution-card--process .solution-card-desc { max-width: none; }
}
.solution-card--process .process { margin-top: 0; }
/* Mixed-case labels read best in the body face at a sentence weight, without the tracking caps need.
   Each label sits on its number's baseline, to its right, in the number's colour. */
.solution-card-kicker {
  display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 14px;
  margin-bottom: 12px;
  font-size: 15px; font-weight: 500; letter-spacing: -.01em; color: var(--blue);
}
.solution-card-label { color: var(--blue-line); }
.solution-card-no {
  display: block;
  font-family: var(--font); font-size: clamp(2.75rem, 5vw, 4rem); font-weight: 700;
  line-height: 1; letter-spacing: -.03em; color: var(--blue-line);
}
.solution-card-title { font-size: clamp(1.625rem, 2.8vw, 2.375rem); font-weight: 700; line-height: 1.3; letter-spacing: -.035em; }
.solution-card-title br { display: none; }
@media (min-width: 640px) { .solution-card-title br { display: inline; } }
.solution-card-desc { margin-top: 18px; max-width: 32em; color: var(--graphite); }
.solution-card-desc br:not(.br-all), .section-lead br { display: none; }
@media (min-width: 640px) { .solution-card-desc br, .section-lead br { display: inline; } }
.solution-card-tags { margin-top: 24px; display: flex; flex-wrap: wrap; gap: 8px 22px; }
.solution-card-tags li { position: relative; padding-left: 14px; font-size: 14.5px; font-weight: 500; }
.solution-card-tags li::before { content: ""; position: absolute; left: 0; top: .62em; width: 6px; height: 6px; background: var(--blue); }
.solution-card-media { overflow: hidden; aspect-ratio: 16 / 10; border-radius: var(--radius); background: var(--night); }
.solution-card-media img { width: 100%; height: 100%; object-fit: cover; transition: transform .9s var(--ease); }
.solution-card:hover .solution-card-media img { transform: scale(1.04); }

/* Part-by-part diagram */
.parts {
  --parts-gap: 56px;
  margin-top: var(--block-gap);
  padding: clamp(24px, 4vw, 56px);
  border-radius: 10px;
  background: var(--paper);
}
.parts-head { max-width: 42em; margin-bottom: clamp(8px, 1vw, 12px); }
.parts-stage { display: grid; gap: 28px; align-items: center; }
/* Desktop: drawing and panel take equal halves; the drawing fills its half. */
@media (min-width: 1024px) { .parts-stage { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--parts-gap); } }
/* The title block starts where the drawing does: its ground shadow begins 10% in (x 80 of 800).
   Percentages here are of the same width as .parts-stage. Phones stay flush with the buttons. */
@media (min-width: 640px) and (max-width: 1023px) { .parts-head { padding-left: 20%; } } /* 12.5% margin + 10% of the 75% drawing */
@media (min-width: 1024px) { .parts-head { padding-left: calc((100% - var(--parts-gap)) * .05); } } /* 10% of the left half */
/* Desktop: the head may run the full width so the second sentence stays on one line. */
@media (min-width: 1024px) {
  /* Centred on the panel, the car would sit level with the buttons and leave a gap under it: lowered a little. */
  .parts-figure { position: relative; top: 8px; }
  .parts-head, .parts-head .block-text { max-width: none; }
  /* At 1024px it runs 8px into the block's padding rather than wrap. */
  .parts-line { white-space: nowrap; }
}
.car { display: block; width: 100%; height: auto; margin-inline: auto; overflow: visible; }
/* Tablet (stacked): 75% of the width, centred. Phones keep the full width so each part stays easy to tap. */
@media (min-width: 640px) and (max-width: 1023px) { .car { width: 75%; } }
/* 3D car (car3d.js) takes the drawing's place where WebGL2 runs; same widths as the drawing. */
.parts.has-3d .car { display: none; }
.car3d { width: 100%; margin-inline: auto; }
@media (min-width: 640px) and (max-width: 1023px) { .car3d { width: 75%; } }
.car3d-canvas { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; cursor: grab; touch-action: pan-y; }
.car3d-canvas.is-over-part { cursor: pointer; }
.car3d-canvas.is-dragging { cursor: grabbing; }
.car-shadow { fill: #E7EAF1; }
/* Turntable: main.js squashes .car-turn and swaps side → front → side (mirrored) → rear views. */
.car-turn, .car-view.is-mirrored { transform-box: view-box; transform-origin: 400px 160px; }
.car-view:not(.is-current) { display: none; }
.car-view.is-mirrored { transform: scale(-1, 1); }
.car [data-part] { fill: var(--paper); stroke: #8C95AB; stroke-width: 2; stroke-linejoin: round; cursor: pointer; }
.car [data-part], .car [data-part] * { transition: fill .35s var(--ease), stroke .35s var(--ease); }
.car [data-part="glass"] { fill: #EEF2FA; }
.car .car-wheel { fill: #272C42; stroke: #272C42; }
.car [data-part]:hover { fill: var(--blue-tint); stroke: var(--blue); }
.car .car-wheel:hover { fill: #3B4372; stroke: #3B4372; }
.car [data-part].is-active { fill: var(--blue); stroke: var(--blue); }
.car-detail { fill: none; stroke: #8C95AB; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; transition: stroke .35s var(--ease); }
.car-rim { fill: none; stroke: rgba(255, 255, 255, .75); stroke-width: 2; stroke-linecap: round; pointer-events: none; }
.car[data-active="paint"] .car-detail { stroke: rgba(255, 255, 255, .7); }
/* Headlights, hood line and grille sit on the 전면부 part, not on the paint. */
.car[data-active="paint"] .car-detail--front { stroke: #8C95AB; }
.car[data-active="front"] .car-detail--front { stroke: rgba(255, 255, 255, .8); }
.car-scanline { stroke: var(--scan); stroke-width: 3; stroke-linecap: round; opacity: 0; pointer-events: none; }
.parts.is-in .car-scanline { animation: car-scan 1.8s cubic-bezier(.45, 0, .2, 1) .2s 1 both; }
@keyframes car-scan {
  0% { transform: translateX(40px); opacity: 0; }
  10%, 85% { opacity: 1; }
  100% { transform: translateX(760px); opacity: 0; }
}

/* The panel is as wide as the button row; the part info takes that width instead of setting it.
   Centred in its space: in the right half on desktop (the drawing fills the left half), under the drawing when stacked. */
.parts-panel { min-width: 0; width: fit-content; max-width: 100%; margin-inline: auto; }
@media (min-width: 1024px) { .parts-panel { min-height: 300px; } }
.parts-info { width: 0; min-width: 100%; }
.parts-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 28px; }
.parts-tabs button {
  height: 40px; padding: 0 16px;
  border: 1px solid var(--line); border-radius: 999px;
  font-size: 14.5px; font-weight: 600; color: var(--graphite);
  transition: background-color .25s var(--ease), border-color .25s var(--ease), color .25s var(--ease);
}
.parts-tabs button:hover { border-color: var(--blue); color: var(--blue); }
.parts-tabs button[aria-selected="true"] { background: var(--blue); border-color: var(--blue); color: #fff; }
/* Phones: two centred rows, three buttons then two (left to wrap, one could drop alone onto the second row).
   A full-width break sits between them; its negative margin takes back the extra row gap it adds. */
@media (max-width: 639px) {
  .parts-tabs { justify-content: center; }
  .parts-tabs::after { content: ""; flex-basis: 100%; order: 1; margin-top: -8px; }
  .parts-tabs button:nth-child(n+4) { order: 2; }
}
/* Heading and check marks start 32px in, so the list does not hug the left edge; the divider lines stay flush with the buttons.
   Phones: 20px, the most that keeps the longest items on one line in the narrow panel. */
.parts-info { --parts-indent: 20px; }
@media (min-width: 640px) { .parts-info { --parts-indent: 32px; } }
.parts-info h4 { padding-left: var(--parts-indent); font-size: clamp(1.75rem, 2.8vw, 2.25rem); font-weight: 700; line-height: 1.2; letter-spacing: -.035em; }
.parts-info ul { margin-top: 20px; border-top: 1px solid var(--line); }
.parts-info li { display: flex; align-items: flex-start; gap: 12px; padding: 14px 0 14px var(--parts-indent); border-bottom: 1px solid var(--line); font-weight: 500; }
.parts-info li::before {
  content: ""; flex: none; width: 18px; height: 18px;
  margin-top: calc((1.7em - 18px) / 2); /* centred on the first line (line-height 1.7) */
  background: var(--blue);
  -webkit-mask: var(--icon-check) center / contain no-repeat;
  mask: var(--icon-check) center / contain no-repeat;
}

/* Process */
.process { margin-top: var(--block-gap); }
.process-track { display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); }
.step { position: relative; display: flex; flex-direction: column; align-items: center; padding-inline: 6px; text-align: center; }
/* Connector: from this icon's centre to the next one's (columns are equal and gapless), 2px through the icon centre.
   Once the block scrolls in, each segment draws .4s after the one before (--step-at) and each icon's ring
   turns blue as the line arrives: step k's segment starts at --step-at, the previous one ends .05s later. */
.step:nth-child(2) { --step-at: .4s; }
.step:nth-child(3) { --step-at: .8s; }
.step:nth-child(4) { --step-at: 1.2s; }
.step:nth-child(5) { --step-at: 1.6s; }
.step:nth-child(6) { --step-at: 2s; }
.step:nth-child(7) { --step-at: 2.4s; }
.step:nth-child(8) { --step-at: 2.8s; }
.step::before {
  content: ""; position: absolute; top: 71px; left: 50%; right: -50%; height: 2px;
  background: var(--blue);
  transform: scaleX(0); transform-origin: left;
  transition: transform .45s linear var(--step-at, 0s);
}
.step:last-child::before { display: none; }
.process.is-in .step::before { transform: scaleX(1); }
.step-no { height: 20px; font-size: 13px; color: var(--blue); font-variant-numeric: tabular-nums; }
.step-icon {
  position: relative; z-index: 1;
  width: 72px; height: 72px; margin-top: 16px; padding: 17px;
  border: 1px solid var(--line); border-radius: 50%;
  background: var(--paper);
  fill: none; stroke: var(--ink); stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round;
  transition: background-color .3s var(--ease), border-color .3s var(--ease), box-shadow .3s var(--ease), stroke .3s var(--ease);
}
/* Ring: the 1px border plus a 1px inset shadow, as thick as the line, without moving the icon. */
.process.is-in .step-icon {
  border-color: var(--blue); box-shadow: inset 0 0 0 1px var(--blue);
  transition: background-color .3s var(--ease), border-color .3s var(--ease) calc(var(--step-at, 0s) + .05s),
    box-shadow .3s var(--ease) calc(var(--step-at, 0s) + .05s), stroke .3s var(--ease);
}
.step:hover .step-icon { background: var(--blue); border-color: var(--blue); stroke: #fff; }
.step-name { margin-top: 16px; font-size: 15.5px; font-weight: 650; letter-spacing: -.02em; }
@media (max-width: 1023px) {
  .process-track {
    grid-template-columns: repeat(8, 132px);
    overflow-x: auto; scroll-snap-type: x mandatory;
    margin-inline: calc(var(--gutter) * -1); padding: 0 var(--gutter) 12px;
    scroll-padding-inline: var(--gutter);
    scrollbar-width: thin;
  }
  .step { scroll-snap-align: start; }
}

/* Vision band */
.vision { position: relative; isolation: isolate; overflow: hidden; margin-top: var(--section-y); color: #fff; background: var(--night); }
.vision-bg { position: absolute; inset: 0; z-index: -1; width: 100%; height: 100%; object-fit: cover; opacity: .55; }
.vision::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg, rgba(10, 15, 44, .94) 0%, rgba(10, 15, 44, .72) 50%, rgba(10, 15, 44, .3) 100%);
}
.vision-inner { padding-block: clamp(96px, 12vw, 160px); }
.vision-title { max-width: 14em; font-size: clamp(2rem, 4vw, 3.25rem); font-weight: 700; line-height: 1.24; letter-spacing: -.035em; }
.vision-text { margin-top: 20px; max-width: 40em; color: rgba(255, 255, 255, .78); }
.vision-list {
  margin-top: 40px; max-width: 640px;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 32px;
  border-top: 1px solid var(--night-line);
}
.vision-list li { padding: 18px 0; border-bottom: 1px solid var(--night-line); font-weight: 600; }

/* ---------- Milestones ---------- */

.history { display: grid; gap: 32px; }
.history-head .eyebrow { margin-bottom: 18px; }
.history-head .section-lead { margin-top: 16px; }
@media (min-width: 1024px) { .history { grid-template-columns: 4fr 8fr; gap: 56px; } }
.tl-year { position: relative; display: grid; gap: 18px; padding: 0 0 52px 34px; }
.tl-year::before { content: ""; position: absolute; left: 5px; top: 16px; bottom: 0; width: 1px; background: var(--line); }
.tl-year:last-child { padding-bottom: 0; }
.tl-year:last-child::before { bottom: 12px; }
.tl-year::after {
  content: ""; position: absolute; left: 0; top: 10px;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--blue); box-shadow: 0 0 0 4px var(--blue-tint);
}
.tl-year-label { font-size: clamp(2rem, 3.4vw, 2.75rem); font-weight: 700; line-height: 1; letter-spacing: -.03em; color: var(--blue); font-variant-numeric: tabular-nums; }
.tl-items { display: grid; gap: 4px; }
.tl-item { display: grid; grid-template-columns: 40px 1fr; gap: 12px; padding: 9px 0; }
.tl-month { color: var(--mute); font-variant-numeric: tabular-nums; }
.tl-item.is-milestone {
  margin: 6px 0; padding: 18px 20px;
  border: 1px solid var(--blue-line); border-radius: 8px;
  background: var(--blue-tint);
}
.tl-item.is-milestone .tl-title { font-size: 1.0625rem; font-weight: 700; }
.tl-item.is-milestone .tl-month { color: var(--graphite); }
.tl-flag { display: block; margin-bottom: 4px; font-size: 13px; font-weight: 600; color: var(--blue); }
.tl-year.is-skeleton::after { background: var(--line); box-shadow: none; }
.sk { display: block; border: 1.5px dashed #C9CFDB; border-radius: 4px; }
.sk--year { width: 104px; height: 36px; }
.sk--line { height: 16px; margin: 6px 0; }

.partners { margin-top: var(--block-gap); --logo-h: 34px; --logo-gap: 40px; --logo-row-gap: clamp(36px, 4vw, 48px); }
@media (min-width: 640px) { .partners { --logo-h: 44px; --logo-gap: 64px; } }
/* Title to logos = logo row to logo row (+8px matches each flowing row's padding). */
.partners > .block-title { margin-bottom: calc(var(--logo-row-gap) + 8px); }
/* Logos stand on their own: no box, one shared height, natural width. */
.logo-row { display: flex; flex-wrap: wrap; align-items: center; gap: 40px var(--logo-gap); }
.logo-cell { display: flex; flex: none; align-items: center; justify-content: center; }
.logo-cell img { width: auto; height: var(--logo-h); }
/* Empty list: dashed placeholder slots. */
.logo-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
@media (min-width: 640px) { .logo-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .logo-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
.logo-cell.is-empty { height: 96px; padding: 20px; border: 1px dashed #C9CFDB; border-radius: var(--radius); }
.logo-cell.is-empty svg { width: 28px; height: 28px; fill: none; stroke: #C1C7D3; stroke-width: 1.5; }
@media (max-width: 639px) { .logo-cell.is-empty:nth-child(n+5) { display: none; } }
/* Flowing rows: each row holds the logos plus hidden copies (--marquee-repeat sets in all), so sliding
   the track by one set — (track width + one gap) ÷ sets — loops without a seam. Hovering pauses every row. */
.marquee-rows { display: grid; row-gap: var(--logo-row-gap); }
/* padding-block keeps the focus ring of linked logos inside the clipped strip */
.marquee { overflow: hidden; padding-block: 8px; -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent); mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent); }
.marquee-track { display: flex; align-items: center; gap: var(--logo-gap); width: max-content; animation: marquee var(--marquee-time, 30s) linear infinite; }
.marquee--reverse .marquee-track { animation-direction: reverse; }
.marquee-set { display: contents; }
.marquee-rows:is(:hover, :focus-within) .marquee-track { animation-play-state: paused; } /* a focused logo stays put */
@keyframes marquee { to { transform: translateX(calc((-100% - var(--logo-gap)) / var(--marquee-repeat, 2))); } }

/* ---------- News ---------- */

.demo-badge {
  display: inline-block; margin-bottom: 20px; padding: 4px 10px; border-radius: 4px;
  background: #FFF1CC; color: #6B4A00; font-size: 13px; font-weight: 600;
}
.news-grid { display: grid; gap: 28px 24px; }
/* One page of 3 news cards = one row from tablet width up; narrower screens stack them.
   (Below 700px a card would be under ~200px, too narrow for its title.) */
@media (min-width: 700px) { .news-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.news-card { display: flex; flex-direction: column; height: 100%; overflow: hidden; border-radius: var(--radius); background: var(--paper); }
.news-thumb { overflow: hidden; aspect-ratio: 16 / 10; background: var(--night); }
.news-thumb img { width: 100%; height: 100%; object-fit: cover; transition: transform .8s var(--ease); }
/* Shown whole (render.js: a picture much wider than the card), on white so a logo banner's own white runs on. */
.news-thumb--whole { background: #fff; }
.news-thumb--whole img { object-fit: contain; }
.news-thumb--fallback { display: grid; place-items: center; }
.news-thumb--fallback img { width: 64px; height: 64px; object-fit: contain; opacity: .9; }
.news-body { flex: 1; display: flex; flex-direction: column; gap: 12px; padding: 20px 22px 24px; }
.news-meta { display: flex; align-items: center; font-size: 13px; color: var(--mute); }
.news-cat { font-weight: 600; color: var(--blue); }
.news-title {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  font-size: 1.125rem; font-weight: 650; line-height: 1.5; letter-spacing: -.02em;
  text-wrap: wrap; /* fill the first line before wrapping (headings are balanced by default) */
}
.news-source { margin-top: auto; font-size: 14px; color: var(--mute); }
a.news-card:hover .news-thumb img { transform: scale(1.05); }
a.news-card:hover .news-title { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }
.news-empty { padding: 80px 24px; border-radius: var(--radius); background: var(--paper); text-align: center; color: var(--graphite); }
.news-empty strong { display: block; margin-bottom: 8px; font-size: 1.25rem; font-weight: 700; color: var(--ink); letter-spacing: -.02em; }

.pager {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-top: 48px;
  justify-content: center; justify-content: safe center;
}
.pager button {
  display: inline-grid; place-items: center;
  min-width: 40px; height: 40px; padding: 0 8px; border-radius: 999px;
  font-size: 15px; font-weight: 600; color: var(--graphite); font-variant-numeric: tabular-nums;
  transition: background-color .2s var(--ease), color .2s var(--ease);
}
.pager button:hover:not(:disabled):not([aria-current]) { background: var(--paper); color: var(--ink); }
.pager button[aria-current="page"] { background: var(--ink); color: #fff; }
.pager button:disabled { opacity: .3; cursor: default; }
.pager svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.pager-gap { min-width: 28px; text-align: center; color: var(--mute); }
@media (max-width: 479px) {
  .pager { gap: 2px; }
  .pager button { min-width: 36px; height: 36px; padding: 0 6px; }
  .pager-gap { min-width: 20px; }
}

/* ---------- News detail page (news.html) ---------- */

.article-page { padding: calc(var(--header-h) + clamp(40px, 6vw, 88px)) 0 var(--section-y); }
.article { max-width: 760px; margin-inline: auto; }
.article > .demo-badge { display: table; }
.article-back {
  display: inline-flex; align-items: center; gap: 4px; margin-left: -4px;
  font-size: 14.5px; font-weight: 600; color: var(--mute);
  transition: color .2s var(--ease);
}
.article-back:hover { color: var(--ink); }
.article-back svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.article-head { margin-top: clamp(28px, 4vw, 44px); }
.article-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: 14px; color: var(--mute); }
.article-cat { font-weight: 600; color: var(--blue); }
.article-meta time { font-family: var(--mono); font-weight: 500; letter-spacing: .02em; word-spacing: -.35em; } /* a mono space is a full digit wide; tighten "2026. 07. 24." */
.article-title { margin-top: 14px; font-size: clamp(1.75rem, 3.6vw, 2.625rem); font-weight: 700; line-height: 1.32; letter-spacing: -.035em; text-wrap: wrap; }
.article-figure { margin-top: clamp(32px, 4vw, 48px); overflow: hidden; border-radius: var(--radius); background: var(--steel); }
.article-figure img { width: 100%; height: auto; }
.article figcaption { padding: 10px 2px 0; font-size: 14px; color: var(--mute); }
.article-figure figcaption { padding: 10px 12px 12px; background: var(--paper); }
.article-gallery { margin-top: clamp(32px, 4vw, 48px); display: grid; gap: 20px 16px; }
@media (min-width: 640px) { .article-gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.article-gallery a { display: block; overflow: hidden; border-radius: var(--radius); background: var(--steel); }
.article-gallery img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; transition: transform .6s var(--ease); }
.article-gallery a:hover img { transform: scale(1.03); }
.article-body { margin-top: clamp(32px, 4vw, 48px); font-size: 1.0625rem; line-height: 1.85; }
.article-body p + p { margin-top: 1.25em; }
/* Last line of a press item, sitting just above the 출처 box it points to. */
.article-note { margin-top: clamp(32px, 4vw, 48px); font-size: 1.0625rem; line-height: 1.85; color: var(--mute); }
.article-note + .article-source { margin-top: 20px; }
.article-source {
  margin-top: 48px; padding: 20px 24px;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 24px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--steel);
}
.article-source p { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; }
.article-source-label { font-size: 13px; font-weight: 600; color: var(--mute); }
.article-source strong { font-weight: 650; }
.article-source-link {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 15px; font-weight: 600; color: var(--blue);
  background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat;
  transition: background-size .35s var(--ease);
}
.article-source-link:hover { background-size: 100% 1px; }
.article-source-link svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.article-nav { margin-top: 56px; display: grid; border-top: 1px solid var(--line); }
@media (min-width: 640px) { .article-nav { grid-template-columns: 1fr 1fr; column-gap: 32px; } }
.article-nav-link { display: grid; gap: 4px; padding: 18px 0; border-bottom: 1px solid var(--line); min-width: 0; }
.article-nav-link[data-newer] { text-align: right; }
@media (max-width: 639px) { .article-nav-link[data-newer] { text-align: left; } }
.article-nav-label { font-size: 13px; font-weight: 600; color: var(--mute); }
.article-nav-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; transition: color .2s var(--ease); }
.article-nav-link:hover .article-nav-title { color: var(--blue); }
.article-nav-empty { display: none; }
@media (min-width: 640px) { .article-nav-empty { display: block; } }
.article-foot { margin-top: 40px; text-align: center; }
.article-missing { margin-top: 40px; }
.article-missing p { margin: 16px 0 28px; color: var(--graphite); }

/* ---------- Contact & footer ---------- */

.contact-grid { display: grid; gap: 56px; }
@media (min-width: 1024px) { .contact-grid { grid-template-columns: 7fr 5fr; gap: 72px; } }
.contact-label { margin-bottom: 16px; font-size: 15px; font-weight: 600; color: rgba(255, 255, 255, .6); }
.contact-email {
  display: inline-block;
  font-size: clamp(1.25rem, 1.8vw, 1.5rem); font-weight: 600; line-height: 1.5;
  background: linear-gradient(currentColor, currentColor) 0 100% / 0 2px no-repeat;
  transition: background-size .45s var(--ease);
  word-break: break-all;
}
.contact-email:hover { background-size: 100% 2px; }
.contact-actions { margin-top: 28px; display: flex; flex-wrap: wrap; gap: 12px; }
.contact-actions[hidden], .contact-actions .btn[hidden] { display: none; }
/* Keeps the line breaks written in data/site.js's address (contact block only). */
.contact-address { font-size: clamp(1.25rem, 1.8vw, 1.5rem); font-weight: 600; line-height: 1.5; white-space: pre-line; }
.contact-address.is-placeholder {
  display: inline-block; padding: 12px 16px;
  border: 1px dashed rgba(255, 255, 255, .3); border-radius: var(--radius);
  font-size: 1rem; font-weight: 500; color: rgba(255, 255, 255, .65);
}

.site-footer { background: var(--night); color: rgba(255, 255, 255, .62); border-top: 1px solid var(--night-line); }
.footer-inner { display: grid; gap: 24px; padding-block: 48px 40px; }
@media (min-width: 900px) {
  .footer-inner { grid-template-columns: auto 1fr auto; align-items: center; gap: 24px 48px; }
}
.footer-logo { width: 120px; height: auto; }
.footer-info { display: flex; flex-wrap: wrap; gap: 6px 28px; font-size: 14px; }
.footer-info > div { display: flex; gap: 8px; }
.footer-info dt { color: rgba(255, 255, 255, .62); }
.footer-info dd { color: rgba(255, 255, 255, .85); }
.footer-info a:hover { color: #fff; }
.footer-info .is-placeholder { color: rgba(255, 255, 255, .62); }
.copyright { font-size: 13px; color: rgba(255, 255, 255, .62); }
@media (min-width: 900px) {
  .copyright { grid-column: 1 / -1; padding-top: 24px; border-top: 1px solid var(--night-line); }
}
.to-top { display: inline-flex; align-items: center; gap: 8px; justify-self: start; font-size: 14px; font-weight: 600; color: #fff; }
.to-top svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: transform .3s var(--ease); }
.to-top:hover svg { transform: translateY(-3px); }
@media (min-width: 900px) { .to-top { grid-column: 3; grid-row: 1; } }

.toast {
  position: fixed; left: 50%; bottom: 28px; z-index: 60;
  width: max-content; max-width: calc(100vw - 32px);
  padding: 12px 20px; border-radius: 24px;
  background: var(--ink); color: #fff; font-size: 14.5px; font-weight: 500; text-align: center;
  opacity: 0; pointer-events: none; transform: translate(-50%, 16px);
  transition: opacity .25s var(--ease), transform .25s var(--ease);
}
.toast.is-visible { opacity: 1; transform: translate(-50%, 0); }

/* ---------- Labels (IBM Plex Mono) ---------- */

.eyebrow {
  margin: 0;
  font-family: var(--mono); font-size: 12px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--blue);
}
/* The title's first letter starts ~.026em in (2px on desktop); the label's starts 1px in. The label begins 7px
   right of the title's first letter. Written as typed, tracked a touch tighter than the other labels. */
.hero-content .eyebrow {
  margin-bottom: 22px; padding-left: calc(max(0px, calc(var(--hero-title-size) * .026 - 1px)) + 7px);
  letter-spacing: .13em; text-transform: none;
  color: var(--scan); animation: hero-fade .9s var(--ease) .05s both;
}.section--contact .eyebrow { color: var(--scan); }
@media (min-width: 1024px) {
  .section-head { row-gap: 18px; }
  .section-head .eyebrow { grid-column: 1 / -1; }
}

.step-no, .tl-month { font-family: var(--mono); font-weight: 500; letter-spacing: .02em; }

/* ---------- Hero scroll cue ---------- */

.scroll-cue {
  position: absolute; z-index: 2;
  right: calc(max(var(--gutter), calc((100vw - 1280px) / 2)) + 60px);
  bottom: clamp(64px, 11vh, 120px);
  display: flex; align-items: center; gap: 14px; height: 44px;
  font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: .22em;
  color: rgba(255, 255, 255, .78);
  animation: hero-fade .9s var(--ease) .9s both;
}
/* A down arrow just before SCROLL, nudging downward, so the cue reads as "scroll down". */
.scroll-cue-arrow {
  width: 10px; height: 14px; margin-right: -4px;
  fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
  animation: scroll-cue-nudge 1.6s ease-in-out infinite;
}
@keyframes scroll-cue-nudge { 0%, 100% { transform: translateY(-2px); } 50% { transform: translateY(2px); } }
.scroll-cue-track { position: relative; overflow: hidden; width: 120px; height: 1px; background: rgba(255, 255, 255, .28); }
.scroll-cue-fill {
  position: absolute; inset: 0;
  background: var(--scan);
  transform: scaleX(var(--p, 1)); transform-origin: left;
}
@media (max-width: 639px) { .scroll-cue { display: none; } }

/* ---------- Scroll reveal (armed by main.js) ---------- */

.reveal-ready .reveal {
  opacity: 0; transform: translateY(16px);
  transition: opacity .8s var(--ease), transform .8s var(--ease);
}
.reveal-ready .reveal.is-shown { opacity: 1; transform: none; }
/* The reviews stay put and their bubbles pop in one after another instead. */
.reveal-ready .voices.reveal { opacity: 1; transform: none; }
.reveal-ready .voices.reveal :is(.voice-list > li, figcaption) {
  opacity: 0; transform: translateY(18px);
  transition: opacity .45s var(--ease), transform .55s cubic-bezier(.34, 1.45, .64, 1);
}
.reveal-ready .voices.reveal.is-shown :is(.voice-list > li, figcaption) { opacity: 1; transform: none; }
.reveal-ready .voices .voice-list > li:nth-child(2) { transition-delay: .14s; }
.reveal-ready .voices .voice-list > li:nth-child(3) { transition-delay: .28s; }
.reveal-ready .voices .voice-list > li:nth-child(4) { transition-delay: .42s; }
.reveal-ready .voices .voice-list > li:nth-child(5) { transition-delay: .56s; }
.reveal-ready .voices figcaption { transition-delay: .8s; }
/* The history stays put and comes in from the top down instead: its heading, then each year (its dot and
   label, its line drawing downward) and each item as it scrolls in, top first (delays set by main.js). */
.reveal-ready .history.reveal { opacity: 1; transform: none; }
.reveal-ready .history :is(.history-head, .tl-item, .tl-year > .tl-year-label) {
  opacity: 0; transform: translateY(16px);
  transition: opacity 1s var(--ease), transform 1s var(--ease);
  transition-delay: var(--row-delay, 0s);
}
.reveal-ready .history .tl-year::after {
  opacity: 0; transform: scale(.4);
  transition: opacity 1s var(--ease), transform 1s var(--ease); transition-delay: var(--row-delay, 0s);
}
.reveal-ready .history .tl-year::before {
  transform: scaleY(0); transform-origin: top;
  transition: transform 2.2s var(--ease); transition-delay: var(--row-delay, 0s);
}
.reveal-ready .history :is(.history-head.is-shown, .tl-item.is-shown, .tl-year.is-shown > .tl-year-label) { opacity: 1; transform: none; }
.reveal-ready .history .tl-year.is-shown::after,
.reveal-ready .history .tl-year.is-shown::before { opacity: 1; transform: none; }
/* 'Shape' (도형) transition: the diagram and the solution intro block share one pinned stage, and the solution
   block (on top) shows through a circle that grows out of the '운전자가 원하는 세차' hub as the page
   scrolls through the scene's extra length. main.js sets the stage's top, the circle and .is-open. */
.shape-ready .shape-scene { margin-top: var(--block-gap); }
/* A spacer, not padding: a sticky box only travels inside its parent's content box. */
.shape-ready .shape-scene::after { content: ""; display: block; height: var(--shape-travel, 80vh); }
.shape-ready .shape-stage { position: sticky; top: var(--shape-pin-top, 0px); display: grid; }
.shape-ready .shape-stage > * { grid-area: 1 / 1; margin-top: 0; }
/* The diagram keeps its own height (the transition starts from its centre on phones and tablets); the solution intro
   block stretches over the whole cell so it covers the diagram once open. */
.shape-ready .shape-stage > .wants { align-self: start; }
.shape-ready .shape-stage > .solution-intro {
  position: relative; z-index: 1; background: var(--paper);
  clip-path: circle(var(--shape-r, 0px) at var(--shape-at, 50% 50%));
}
.shape-ready .shape-stage > .solution-intro.is-open { clip-path: none; }
/* From 20% along until it completes, the page behind is blurred (the header stays sharp above it); the solution
   intro block sits above the blur. */
.shape-ready .shape-stage > .solution-intro.is-front { z-index: 71; }
.shape-backdrop {
  position: fixed; inset: 0; z-index: 70; pointer-events: none;
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  opacity: 0; visibility: hidden;
  transition: opacity .4s var(--ease), visibility 0s linear .4s;
}
.shape-blur .shape-backdrop { opacity: 1; visibility: visible; transition: opacity .4s var(--ease); }

/* ---------- 404 ---------- */

.notfound { min-height: 100vh; min-height: 100svh; display: grid; place-items: center; background: var(--night); color: #fff; text-align: center; }
.notfound-inner { padding: 48px var(--gutter); }
.notfound img { width: 140px; margin: 0 auto 40px; }
.notfound h1 { font-size: clamp(1.75rem, 4vw, 2.5rem); font-weight: 700; letter-spacing: -.03em; }
.notfound p { margin: 12px 0 32px; color: rgba(255, 255, 255, .7); }

/* ---------- Reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
  .hero-scan, .car-scanline { display: none; }
  /* main.js arms no reveals under reduced motion; this shows any it armed before the setting was switched on. */
  .reveal-ready .reveal { opacity: 1; transform: none; }
  /* Logos stand still: one set per row, wrapping. */
  .marquee { -webkit-mask-image: none; mask-image: none; }
  .marquee-track { animation: none !important; width: auto; flex-wrap: wrap; row-gap: 32px; }
  .marquee-set[aria-hidden="true"] { display: none; }
}
