/* =========================================================
   Shiftworks Studio — typographic hero (GSAP-style)
   General Sans · dark + warm cream · animated brand pinwheel
   ========================================================= */

/* General Sans is loaded from Fontshare in index.html (free web licence) */

/* =========================================================
   THEME TOKENS
   The design runs on a foreground/background invert system, so
   --cream is always the "foreground/ink" and --bg the "surface".
   Dark is the default (also the no-JS fallback); light overrides
   via html[data-theme="light"]. A floating toggle swaps the
   data-theme attribute; the early head script sets it pre-paint.
   ========================================================= */
:root {
  --font: "General Sans", "Helvetica Neue", Helvetica, system-ui, -apple-system, "Segoe UI", sans-serif;
  --accent: #ff6a1f;               /* brand orange — constant across themes */
  --pad: clamp(20px, 4vw, 64px);   /* page edge padding */

  /* ---- DARK (default) ---- */
  --bg: #0c0c0d;
  --cream: #f3efe3;
  --muted: rgba(243, 239, 227, 0.55);
  --line: rgba(243, 239, 227, 0.22);

  --surface-1: #161618;            /* hero radial — centre */
  --surface-2: #0a0a0b;            /* hero radial — edge */
  --grain-opacity: 0.05;
  --grain-blend: overlay;
  --logo-invert: 0;                /* wordmark ships white → no invert on dark */

  --card-bg: #161617;
  --card-shadow: 0 30px 90px rgba(0, 0, 0, 0.55);
  --scrim: rgba(8, 8, 9, 0.38);
  --field-bg: rgba(255, 255, 255, 0.04);
  --field-bg-focus: rgba(255, 255, 255, 0.06);
  --placeholder: rgba(243, 239, 227, 0.35);
  --note-success: #8fd6ad;
  --note-error: #f0a59c;

  --solid-bg: var(--cream);        /* Send button: cream fill, ink text */
  --solid-bg-hover: #ffffff;
  --solid-fg: var(--bg);

  /* decorative cluster stops (B/C/D vary by theme; A + spark stay orange) */
  --sB1: #cbb9f2; --sB2: #8e78d8;  /* lilac */
  --sC1: #deecf2; --sC2: #9fc4d4;  /* pale blue (star) */
  --sD1: #f8b49b; --sD2: #f3849f;  /* pink (pill) */
}

/* ---- LIGHT (override) ---- */
html[data-theme="light"] {
  --bg: #f2f3f5;                   /* cool light grey surface */
  --cream: #16171a;               /* near-black ink */
  --muted: rgba(22, 23, 26, 0.56);
  --line: rgba(22, 23, 26, 0.16);

  --surface-1: #f8f9fb;
  --surface-2: #eceef1;
  --grain-opacity: 0.045;
  --grain-blend: multiply;
  --logo-invert: 1;                /* invert the white wordmark to ink */

  --card-bg: #ffffff;
  --card-shadow: 0 30px 80px rgba(20, 24, 28, 0.16);
  --scrim: rgba(20, 22, 26, 0.28);
  --field-bg: rgba(0, 0, 0, 0.03);
  --field-bg-focus: rgba(0, 0, 0, 0.05);
  --placeholder: rgba(22, 23, 26, 0.38);
  --note-success: #1c7a4f;
  --note-error: #c0392b;

  --solid-bg: var(--accent);       /* Send button: orange fill, ink text */
  --solid-bg-hover: #ff7d3a;
  --solid-fg: #16171a;

  --sB1: #cdd2d8; --sB2: #a6adb5;  /* cool grey */
  --sC1: #2b2d31; --sC2: #16171a;  /* ink (star anchor) */
  --sD1: #ffd9c2; --sD2: #ffb089;  /* pale orange (pill) */
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body { height: 100%; background: var(--bg); }

body {
  font-family: var(--font);
  color: var(--cream);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; }

/* ---- Shell ---- */
.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  padding: var(--pad);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  /* subtle depth */
  background:
    radial-gradient(120% 80% at 50% 22%, var(--surface-1) 0%, var(--surface-2) 68%);
}

/* fine grain for that premium texture */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: var(--grain-opacity);
  mix-blend-mode: var(--grain-blend);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---- Top bar ---- */
.topbar {
  position: relative;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.brand { line-height: 0; }
/* wordmark SVG ships white; invert it to ink when the light theme is active */
.brand img { height: 20px; width: auto; display: block; filter: invert(var(--logo-invert)); transition: filter 0.25s ease; }
/* email now lives in the bottom row */
.contact-mail {
  flex-shrink: 0;
  font-size: clamp(0.85rem, 1.1vw, 1rem);
  letter-spacing: -0.01em;
  color: var(--muted);
  transition: color 0.25s ease;
}
.contact-mail:hover { color: var(--cream); }

/* ---- Center stage ---- */
.stage {
  position: relative;
  z-index: 2;
  flex: 1;
  display: flex;
  align-items: center;
}

.display {
  position: relative;
  width: 100%;
  max-width: none;             /* span the full viewport width */
  z-index: 2;                  /* between the wave (behind) and the spark (in front) */
  perspective: 900px;          /* 3D depth for the GSAP character flip-in */
  padding-top: clamp(44px, 5.5vw, 104px); /* mark overlaps the top of line 1 */
  font-weight: 500;
  font-size: clamp(2.6rem, 12vw, 13rem);
  line-height: 0.9;
  letter-spacing: -0.04em;
  color: var(--cream);
}

/* ---- Animated brand mark (orbit / motion in sync) ---- */
.flair {
  position: absolute;
  top: clamp(8px, 2.5vw, 40px);
  left: clamp(2px, 6vw, 96px);   /* sits over/among the first line */
  width: clamp(88px, 9.5vw, 162px);
  z-index: 4;                    /* above the type so it blends between letters */
  perspective: 760px;
  pointer-events: none;
}
.flair__svg { width: 100%; height: auto; display: block; overflow: visible; }

/* filled-shapes cluster slowly orbits; the star spins within it */
.shapes { transform-box: view-box; transform-origin: 50px 50px; animation: shapes-spin 26s linear infinite; }
.shapes__star { transform-box: fill-box; transform-origin: center; animation: shapes-spin 12s linear infinite reverse; }
@keyframes shapes-spin { to { transform: rotate(360deg); } }

/* ---- Decorative sparkle blended in front of the type ---- */
.deco { position: absolute; pointer-events: none; line-height: 0; }
.deco svg { width: 100%; height: auto; display: block; overflow: visible; }

.deco--spark {
  z-index: 5;
  right: clamp(40px, 13vw, 230px);
  top: 20%;
  width: clamp(24px, 3vw, 50px);
  animation: spark-spin 11s linear infinite;
}
.deco--spark svg { animation: spark-pulse 3.2s ease-in-out infinite; }
@keyframes spark-spin { to { transform: rotate(360deg); } }
@keyframes spark-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.18); } }

/* ---- Bottom meta row ---- */
.meta {
  position: relative;
  z-index: 3;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
}
.brackets {
  max-width: 34ch;
  font-size: clamp(0.82rem, 1.15vw, 1rem);
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: var(--muted);
}
.brackets .brk {
  color: var(--cream);
  opacity: 0.85;
}
.brackets__text { color: var(--muted); }

/* ---- Pill CTA ---- */
.pill {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 22px;
  background: transparent;     /* was defaulting to the button's light UA bg → text invisible */
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: clamp(0.85rem, 1.1vw, 1rem);
  letter-spacing: -0.01em;
  color: var(--cream);
  transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}
.pill__icon { width: 18px; height: 18px; transition: transform 0.3s ease; }
.pill:hover {
  background: var(--cream);
  color: var(--bg);
  border-color: var(--cream);
}
.pill:hover .pill__icon { transform: translate(2px, -2px); }

/* ---- Per-character spans (added by intro.js) ---- */
.display .word { display: inline-block; white-space: nowrap; }  /* keep each word unbroken */
.display .char { display: inline-block; }                       /* float layer */
.display .char-inner {
  display: inline-block;                                         /* cursor-reaction layer */
  will-change: transform;
  transition: color 0.3s ease;
}

/* =========================================================
   Entrance animation — pure CSS (no library, can't be blocked)
   Each element starts in its keyframe "from" state via
   animation-fill-mode: both, then animates to visible.
   ========================================================= */
@keyframes char-in {
  0%   { opacity: 0; transform: translateY(0.85em) rotate(7deg); filter: blur(8px); }
  55%  { filter: blur(0); }
  100% { opacity: 1; transform: translateY(0) rotate(0); filter: blur(0); }
}
@keyframes char-wave {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-0.018em); }
}
@keyframes fade-up {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes fade-down {
  from { opacity: 0; transform: translateY(-12px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes flair-in {
  from { opacity: 0; transform: scale(0) rotate(-140deg); }
  to   { opacity: 1; transform: scale(1) rotate(0deg); }
}
@keyframes flair-flip {
  0%, 64%  { transform: rotateY(0deg); }
  100%     { transform: rotateY(360deg); }   /* periodic GSAP-style flip */
}
@keyframes headline-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-10px); }
}

.brand       { animation: fade-down 0.7s ease both 0.1s; }
.topbar .pill { animation: fade-down 0.7s ease both 0.2s; }

/* mark: one-time spring-in (the shapes keep orbiting inside) */
.flair__svg { animation: flair-in 1.1s cubic-bezier(0.34, 1.56, 0.64, 1) both 0.25s; }

/* no-GSAP fallback entrance (the GSAP path adds .gsap-on to disable this) */
.display .char-inner {
  animation:
    char-in 0.7s cubic-bezier(0.2, 0.85, 0.25, 1) both calc(0.35s + var(--i, 0) * 0.028s),
    char-wave 3.6s ease-in-out infinite calc(1.6s + var(--i, 0) * 0.05s);
}
.gsap-on .display .char-inner { animation: none; }

/* (the per-character travelling wave above carries the ongoing life) */

.brackets { animation: fade-up 0.8s ease both 1.4s; }
.contact-mail { animation: fade-up 0.8s ease both 1.5s; }

/* ---- Small screens ---- */
@media (max-width: 720px) {
  .topbar { gap: 12px; }
  .topbar .pill { padding: 11px 16px; font-size: 0.85rem; }
  .meta {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }
  .flair { width: 62px; top: 6px; left: 10px; }
  .deco--spark { width: 30px; right: 9vw; top: 15%; }
  /* modal spans the width and grows out of the top-bar CTA on phones.
     transform-origin sits under the CTA (top-right) so the liquid open
     reads as the panel emerging from the button, not from mid-screen. */
  .modal__card {
    left: var(--pad);
    right: var(--pad);
    top: calc(var(--pad) + 46px);
    width: auto;
    max-width: none;
    transform-origin: top right;
  }
}

@media (prefers-reduced-motion: reduce) {
  .topbar__mail, .pill, .pill__icon { transition: none; }
  .shapes,
  .shapes__star,
  .flair__svg,
  .brand,
  .topbar__mail,
  .brackets,
  .meta .pill,
  .display,
  .display .char-inner,
  .deco--spark,
  .deco--spark svg,
  .theme-toggle { animation: none; }
}

/* =========================================================
   Contact modal
   ========================================================= */
.modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  visibility: hidden;
  pointer-events: none;
  transition: visibility 0.5s ease;
}
.modal.is-open { visibility: visible; pointer-events: auto; }

.modal__backdrop {
  position: absolute;
  inset: 0;
  background: var(--scrim);   /* soft scrim, no blur — hero stays clear */
  opacity: 0;
  transition: opacity 0.5s ease;
}
.modal.is-open .modal__backdrop { opacity: 1; }

/* Panel grows DOWN out of the CTA (now top-right) with a liquid blob morph */
.modal__card {
  position: absolute;
  right: var(--pad);
  top: var(--pad);
  width: min(420px, calc(100vw - 2 * var(--pad)));
  max-height: min(82vh, 720px);
  overflow-y: auto;
  transform-origin: top right;        /* grows out of the CTA corner */
  background: var(--card-bg);
  border: 1px solid var(--line);
  border-radius: 24px;
  padding: clamp(24px, 3vw, 38px);
  box-shadow: var(--card-shadow);
  opacity: 0;
  transform: scale(0.6);
  pointer-events: none;
  transition: opacity 0.28s ease, transform 0.4s cubic-bezier(0.3, 0.8, 0.3, 1);
}
.modal.is-open .modal__card {
  pointer-events: auto;
  animation: card-in 0.5s cubic-bezier(0.34, 1.4, 0.5, 1) both;
}
/* clean spring-scale out of the CTA corner */
@keyframes card-in {
  0%   { opacity: 0; transform: scale(0.6); }
  60%  { opacity: 1; }
  100% { opacity: 1; transform: scale(1); }
}
.modal.is-open .modal__card > * { animation: content-in 0.4s ease both 0.16s; }
@keyframes content-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

.modal__close {
  position: absolute;
  top: 18px;
  right: 18px;
  width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--cream);
  cursor: pointer;
  transition: background-color 0.25s ease, color 0.25s ease;
}
.modal__close svg { width: 18px; height: 18px; }
.modal__close:hover { background: var(--cream); color: var(--bg); }

.modal__eyebrow {
  font-size: 0.85rem;
  letter-spacing: -0.01em;
  color: var(--muted);
  margin-bottom: 10px;
}
.modal__title {
  font-weight: 500;
  font-size: clamp(1.6rem, 3.4vw, 2.3rem);
  line-height: 1.05;
  letter-spacing: -0.03em;
  margin-bottom: 26px;
}

.form .field {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 18px;
}
.form label {
  font-size: 0.82rem;
  letter-spacing: -0.01em;
  color: var(--muted);
}
.form input,
.form textarea {
  width: 100%;
  font-family: inherit;
  font-size: 1rem;
  color: var(--cream);
  background: var(--field-bg);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 13px 15px;
  transition: border-color 0.25s ease, background-color 0.25s ease;
}
.form textarea { resize: vertical; min-height: 96px; }
.form input::placeholder,
.form textarea::placeholder { color: var(--placeholder); }
.form input:focus,
.form textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--field-bg-focus);
}

/* hCaptcha widget (dark theme) — scaled by JS to fill the form width, flush-left */
.captcha-wrap { margin: 2px 0 18px; min-height: 78px; overflow: hidden; }
.h-captcha { transform-origin: left top; }

.pill--solid {
  width: 100%;
  justify-content: center;
  margin-top: 6px;
  background: var(--solid-bg);        /* themed: cream (dark) / orange (light) */
  color: var(--solid-fg);
  border-color: var(--solid-bg);
  cursor: pointer;
}
.pill--solid:hover { background: var(--solid-bg-hover); color: var(--solid-fg); border-color: var(--solid-bg-hover); }

.form__note {
  margin-top: 14px;
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--muted);
}
.form__note.is-success { color: var(--note-success); }
.form__note.is-error { color: var(--note-error); }

/* honeypot — visually hidden, off-screen, not focusable */
.hp {
  position: absolute !important;
  left: -9999px !important;
  width: 1px; height: 1px;
  opacity: 0; pointer-events: none;
}

.pill--solid:disabled { opacity: 0.6; cursor: default; }

/* the trigger pill is a <button> now */
button.pill { cursor: pointer; font: inherit; }

/* =========================================================
   Theme-driven decorative cluster stops
   The inline stop-colors in the SVG are a no-CSS fallback;
   these rules drive the per-theme colours (A + spark stay orange).
   ========================================================= */
#fB stop:first-child { stop-color: var(--sB1); }
#fB stop:last-child  { stop-color: var(--sB2); }
#fC stop:first-child { stop-color: var(--sC1); }
#fC stop:last-child  { stop-color: var(--sC2); }
#fD stop:first-child { stop-color: var(--sD1); }
#fD stop:last-child  { stop-color: var(--sD2); }

/* =========================================================
   Floating theme toggle
   ========================================================= */
.theme-toggle {
  position: fixed;
  right: var(--pad);
  bottom: calc(var(--pad) + 54px);
  z-index: 40;
  width: 46px; height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--card-bg);
  color: var(--cream);
  cursor: pointer;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.18);
  transition: background-color 0.25s ease, color 0.25s ease,
              border-color 0.25s ease, transform 0.25s ease;
  animation: fade-up 0.8s ease both 1.6s;
}
.theme-toggle:hover {
  background: var(--cream);
  color: var(--bg);
  border-color: var(--cream);
  transform: translateY(-2px);
}
.theme-toggle svg { width: 20px; height: 20px; display: block; }
/* dark shows the sun (click → light); light shows the moon (click → dark) */
.theme-toggle .icon-moon { display: none; }
html[data-theme="light"] .theme-toggle .icon-sun { display: none; }
html[data-theme="light"] .theme-toggle .icon-moon { display: block; }

@media (max-width: 720px) {
  .theme-toggle { width: 42px; height: 42px; bottom: calc(var(--pad) + 46px); }
}
