/* Page CSS on top of the taste kit (assets/system.css): the night grade, the renders, and the few
   parts the kit leaves to the page. Day = white / black / lime, night = black / white / lime. */

/* Night grade: the same three colours, swapped */
html[data-theme="dark"] {
  --p-bg: #0a0a0a; --p-surface: #161616; --p-ink: #ffffff; --p-muted: #a3a3a3;
  --p-action: #c6ff00; --p-action-ink: #0a0a0a;
  --p-inv-bg: #ffffff; --p-inv-surface: #f1f1f1; --p-inv-ink: #0a0a0a; --p-inv-muted: #6c6c6c;
  --p-inv-action: #0a0a0a; --p-inv-action-ink: #ffffff;
  color-scheme: dark;
}
/* Day grade keeps lime as the one filled action; its black label reads at 16:1 */
html[data-theme="light"] { --p-action: #c6ff00; --p-action-ink: #0a0a0a; color-scheme: light; }
html[data-theme="light"] .btn--primary { box-shadow: inset 0 0 0 1px rgba(10, 10, 10, .14); }

/* Renders: the client's 3D work, set in black and white so the page keeps one accent.
   Night: their black ground disappears into the page. Day: inverted, their ground turns white. */
img.render { filter: grayscale(1) contrast(1.08); mix-blend-mode: screen; }
html[data-theme="light"] img.render { filter: grayscale(1) invert(1) contrast(1.05); mix-blend-mode: multiply; }
.hero__stage img.render { object-fit: contain; }
.tile__media:has(> img.render) { background: var(--bg); }

/* Theme and language controls in the bar */
.site-controls { display: flex; align-items: center; gap: var(--s-2); }
.site-toggle, .site-lang {
  height: var(--btn-h, 44px); min-width: 44px; border-radius: var(--r-btn); border: 1px solid var(--line-strong);
  background: transparent; color: var(--ink); font: 500 var(--t-small)/1 var(--font-text); cursor: pointer;
}
.site-toggle { display: inline-grid; place-items: center; padding: 0; }
.site-lang { padding: 0 var(--s-3); }
.site-lang option { background: var(--bg); color: var(--ink); }
.site-toggle:hover, .site-lang:hover { border-color: var(--ink); }
.site-toggle__sun { display: none; }
html[data-theme="light"] .site-toggle__sun { display: block; }
html[data-theme="light"] .site-toggle__moon { display: none; }
@media (max-width: 639px) { .site-controls { gap: var(--s-1); } }

/* The hero kicker's dot is the accent */
.hero__kicker .dot { background: var(--accent); }

/* Satisfied clients: the figure above the statement */
.clients-stats { margin-bottom: var(--s-7); }
.clients-stats .clients-stat { font-size: var(--t-h1); color: var(--ink); }
.clients-stat::after { content: ""; display: inline-block; width: .16em; height: .16em; margin-left: .06em; border-radius: 50%; background: var(--accent); vertical-align: .62em; }
.clients-stats dt { font-size: var(--t-lead); color: var(--muted); }

/* Services: the tile's link sits under its text */
.services { --tile-ratio: 16 / 9; }
.services .tile > .link { justify-self: start; }
.tg-icon { flex: none; }

/* Process: four numbered steps beside the prices */
.steps-head { font-size: var(--t-card); font-weight: 500; margin: 0 0 var(--s-4); }
.steps { list-style: none; margin: 0; padding: 0; counter-reset: step; }
.steps > li { display: grid; grid-template-columns: 40px 1fr; gap: var(--s-4); padding-block: var(--s-4); border-bottom: 1px solid var(--line); }
.steps > li::before { counter-increment: step; content: counter(step); display: inline-grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; background: var(--accent); color: var(--accent-ink); font: 500 var(--t-small)/1 var(--font-text); }
.steps .steps__title { font-weight: 500; margin: 0 0 var(--s-1); color: var(--ink); }
.steps p { margin: 0; color: var(--muted); }

/* Team: the one person, under the close's words */
.team-card { display: grid; justify-items: start; gap: var(--s-4); margin-top: var(--s-7); }
.team-card__avatar { width: 88px; height: 88px; border-radius: var(--r-md); display: grid; place-items: center; background: var(--accent); color: var(--accent-ink); font: 400 44px/1 var(--font-display); }
.team-card__name { font-size: var(--t-card); font-weight: 500; margin: 0 0 var(--s-1) !important; }
.team-card__info p { margin: 0; }
.team-card__links { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-5); margin-top: var(--s-2) !important; }

/* A 320px phone: the hero holds the main button, so the bar keeps the name and the menu */
@media (max-width: 359px) {
  .nav:not(.is-open) .nav__actions { display: none; }
  .nav:not(.is-open) .nav__toggle { margin-left: auto; }
}

/* Price rows: the line under each name */
.rows .rows__name small { display: block; font-weight: 400; color: var(--muted); font-size: var(--t-small); }

/* Day grade: lime text on white does not read, so the statement's strong words turn ink on a lime ground */
html[data-theme="light"] .mo-wh strong .mo-w.is-on { color: var(--ink); background: var(--p-accent); box-shadow: 0 0 0 .06em var(--p-accent); }
@media (prefers-reduced-motion: reduce) { html[data-theme="light"] .mo-wh strong .mo-w { color: var(--ink); background: var(--p-accent); } }

/* ---------------------------------------------------------------- animations
   Every loop and entrance below rests under reduced motion (the block at the end). */

/* Renders float slowly; `translate`/`rotate` leave the kit's hover zoom (transform) free */
@keyframes render-float {
  0%, 100% { translate: 0 0; rotate: 0deg; }
  50% { translate: 0 -14px; rotate: 1.6deg; }
}
.hero__stage img.render { animation: render-float 9s ease-in-out infinite; }
.services .tile:nth-child(1) img.render { animation: render-float 8s ease-in-out infinite; }
.services .tile:nth-child(2) img.render { animation: render-float 8s ease-in-out -4s infinite; }

/* The lime dot beside 100+ pulses */
@keyframes dot-pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--p-accent) 70%, transparent); }
  100% { box-shadow: 0 0 0 .22em transparent; }
}
.clients-stat::after { animation: dot-pulse 2.2s ease-out infinite; }

/* The figure rolls up once it is on screen (script.js sets the digits) */
.clients-stat { font-variant-numeric: tabular-nums; }

/* Steps: the numbers light up one after another when the list comes into view */
.anim .steps > li::before { scale: .4; opacity: 0; transition: scale 500ms cubic-bezier(.34, 1.56, .64, 1), opacity 300ms ease; }
.anim .steps.is-in > li::before { scale: 1; opacity: 1; }
.anim .steps.is-in > li:nth-child(2)::before { transition-delay: 150ms; }
.anim .steps.is-in > li:nth-child(3)::before { transition-delay: 300ms; }
.anim .steps.is-in > li:nth-child(4)::before { transition-delay: 450ms; }

/* Price rows: the value slides a little toward the pointer */
.rows > li .rows__value { transition: translate 250ms ease, color 250ms ease; }
.rows > li:hover .rows__value { translate: -6px 0; }

/* The person's avatar answers the pointer */
.team-card__avatar { transition: rotate 300ms ease, scale 300ms ease; }
.team-card:hover .team-card__avatar { rotate: -6deg; scale: 1.05; }

@media (prefers-reduced-motion: reduce) {
  img.render, .clients-stat::after { animation: none !important; }
  .anim .steps > li::before { scale: 1; opacity: 1; transition: none; }
  .rows > li:hover .rows__value, .team-card:hover .team-card__avatar { translate: none; rotate: none; scale: none; }
}

/* ---------------------------------------------------------------- page load
   CSS only, so it plays even before script runs: the bar drops in, the headline is unmasked line by line,
   the lead and buttons rise after it, and the render grows out of a blur. */
@keyframes load-drop { from { translate: 0 -100%; opacity: 0; } }
@keyframes load-unmask { from { clip-path: inset(0 0 100% 0); translate: 0 .35em; } to { clip-path: inset(0 0 -10% 0); translate: 0 0; } }
@keyframes load-rise { from { opacity: 0; translate: 0 24px; } }
@keyframes load-grow { from { opacity: 0; scale: .82; filter: blur(14px); } }
@media (prefers-reduced-motion: no-preference) {
  .nav { animation: load-drop 700ms cubic-bezier(.2, .8, .2, 1) both; }
  .hero h1 { animation: load-unmask 900ms cubic-bezier(.2, .8, .2, 1) 150ms both; }
  .hero__lead { animation: load-rise 700ms cubic-bezier(.2, .8, .2, 1) 450ms both; }
  .hero .btn-row { animation: load-rise 700ms cubic-bezier(.2, .8, .2, 1) 600ms both; }
  .hero__stage { animation: load-grow 1200ms cubic-bezier(.2, .8, .2, 1) 300ms both; }
}

/* ---------------------------------------------------------------- scroll
   script.js marks what to reveal (.rv), adds .is-in as each block reaches the screen, staggers siblings
   with --rv-i, moves the hero render with the scroll (--hero-y) and fills the progress bar. */
.scroll-progress { position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 60; background: var(--p-accent); transform-origin: 0 50%; scale: 0 1; pointer-events: none; }
.anim .rv { opacity: 0; translate: 0 40px; transition: opacity 800ms cubic-bezier(.2, .8, .2, 1), translate 800ms cubic-bezier(.2, .8, .2, 1); transition-delay: calc(var(--rv-i, 0) * 110ms); }
.anim .rv.rv--left { translate: -48px 0; }
.anim .rv.rv--scale { translate: 0 0; scale: .92; transition-property: opacity, scale; }
.anim .rv.is-in { opacity: 1; translate: 0 0; scale: 1; }
.anim .section-head h2.rv { clip-path: inset(0 0 100% 0); translate: 0 .4em; transition-property: opacity, translate, clip-path; }
.anim .section-head h2.rv.is-in { clip-path: inset(0 0 -10% 0); }
.anim .hero__in { translate: 0 calc(var(--hero-y, 0) * 1px); }
.anim .hero__stage img.render { opacity: var(--hero-fade, 1); }
@media (prefers-reduced-motion: reduce) {
  .scroll-progress { display: none; }
  .anim .rv { opacity: 1; translate: none; scale: none; clip-path: none; transition: none; }
}
