/* ============================================================================
   upon / base style  v0.1
   The fundament every experiment and the final site load first.

   One idea runs through all of it: BUILT IN THE OPEN. Things show their
   skeleton (points, lines) for a moment, then resolve into the finished thing.

   Pair with base/upon.js, which drives the colour drift, the "build" reveals
   and the constructing wordmark.
   ========================================================================== */

/* ---- 1. type: two voices ----------------------------------------------------
   Tomato Grotesk speaks (headlines, statements, body).
   JetBrains Mono annotates (labels, numbers, data, UI chrome).
   Nothing else. */
@font-face{ font-family:'Tomato Grotesk'; src:url('./fonts/TomatoGrotesk-Light.otf')   format('opentype'); font-weight:300; font-style:normal; font-display:swap; }
@font-face{ font-family:'Tomato Grotesk'; src:url('./fonts/TomatoGrotesk-Regular.otf') format('opentype'); font-weight:400; font-style:normal; font-display:swap; }
@font-face{ font-family:'Tomato Grotesk'; src:url('./fonts/TomatoGrotesk-Medium.otf')  format('opentype'); font-weight:500; font-style:normal; font-display:swap; }
@font-face{ font-family:'Tomato Grotesk'; src:url('./fonts/TomatoGrotesk-Slanted.otf') format('opentype'); font-weight:400; font-style:italic; font-display:swap; }
@font-face{ font-family:'JetBrains Mono'; src:url('./fonts/JetBrainsMono-VariableFont_wght.ttf') format('truetype'); font-weight:100 800; font-style:normal; font-display:swap; }

/* ---- 2. colour: one hue, everything else is an offset from it ---------------
   --hue is the only moving part. upon.js turns it once around the wheel every
   92 s (the coming-soon page's rhythm). Every colour is OKLCH with FIXED
   lightness, so the tint wanders but contrast never changes.
   At --hue: 277 every token is exactly the brand hex in its comment. */
:root{
  --hue: 277;

  --ink:    #14163a;   /* text, points, fills */
  --paper:  #eeedf2;   /* page */
  --card:   #f7f6f9;   /* raised surfaces */
  --line:   #8c8eae;   /* construction: handles, secondary lines */
  --guide:  #b9bad0;   /* construction: ruled guides */
  --accent: #ffc59d;   /* the logo's peach. Rationed: once per view, if that */
}
@supports (color: oklch(50% 0.1 calc(1 + 1))){
  :root{
    --ink:    oklch(22.2% 0.068  var(--hue));
    --paper:  oklch(94.8% 0.0067 calc(var(--hue) + 18));
    --card:   oklch(97.4% 0.004  calc(var(--hue) + 18));
    --line:   oklch(65.6% 0.0475 calc(var(--hue) + 5));
    --guide:  oklch(79.5% 0.031  calc(var(--hue) + 7));
    --accent: oklch(86.6% 0.085  calc(var(--hue) - 221));
  }
}
:root{
  --grid: color-mix(in oklab, var(--ink) 4.5%, transparent);
  --rule: color-mix(in oklab, var(--ink) 16%, transparent);
  --soft: color-mix(in oklab, var(--ink) 62%, transparent);   /* secondary text */

  /* ---- 3. type scale ---- */
  --font-display: 'Tomato Grotesk', ui-sans-serif, -apple-system, system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --t-display: clamp(56px, 9.4vw, 152px);   /* one per page, the statement */
  --t-headline: clamp(38px, 5.4vw, 84px);
  --t-title: clamp(26px, 2.9vw, 42px);
  --t-lead: clamp(18px, 1.5vw, 22px);
  --t-body: 16px;
  --t-small: 13px;
  --t-label: 10.5px;                        /* mono, uppercase, tracked */
  --t-data: 12px;                           /* mono numbers */

  /* ---- 4. space + grid ---- */
  --unit: 24px;                             /* the construction grid you see */
  --gutter: clamp(16px, 3vw, 40px);
  --max: 1320px;
  --cols: 12;

  /* ---- 5. motion: one habit ----
     Things arrive fast and land softly (out), points pop with a small
     overshoot (back), lines travel evenly (in-out). */
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --ease-back: cubic-bezier(.34, 1.56, .64, 1);
  --ease-inout: cubic-bezier(.65, 0, .35, 1);
  --d-fast: .25s;
  --d: .6s;
  --d-slow: 1.1s;
  --stagger: 70ms;
}

/* ---- 6. foundation ---- */
*,*::before,*::after{ box-sizing:border-box }
html{ -webkit-text-size-adjust:100%; text-size-adjust:100% }
body{
  margin:0; color:var(--ink);
  font:400 var(--t-body)/1.55 var(--font-display);
  background:
    linear-gradient(var(--grid) 1px, transparent 1px) 0 0 / var(--unit) var(--unit),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px) 0 0 / var(--unit) var(--unit),
    var(--paper);
  -webkit-font-smoothing:antialiased;
}
::selection{ background:var(--accent); color:var(--ink) }
img, svg, video{ display:block; max-width:100% }
a{ color:inherit }

/* ---- 7. type classes ---- */
.display,.headline,.title{ font-family:var(--font-display); font-weight:400; margin:0; letter-spacing:-.012em }
.display { font-size:var(--t-display);  line-height:.94 }
.headline{ font-size:var(--t-headline); line-height:1 }
.title   { font-size:var(--t-title);    line-height:1.08; letter-spacing:-.006em }
.lead    { font-size:var(--t-lead); line-height:1.5; max-width:46ch }
.soft    { color:var(--soft) }
.label{
  font:500 var(--t-label)/1.3 var(--font-mono);
  letter-spacing:.2em; text-transform:uppercase;
}
.data{ font:400 var(--t-data)/1.5 var(--font-mono); letter-spacing:.02em; font-variant-numeric:tabular-nums }

/* ---- 8. layout ---- */
.wrap{ width:100%; max-width:var(--max); margin:0 auto; padding-inline:var(--gutter) }
.cols{ display:grid; grid-template-columns:repeat(var(--cols), minmax(0,1fr)); column-gap:var(--gutter) }
.rule{ height:1px; background:var(--rule); border:0; margin:0 }

/* ---- 9. pieces ---- */
.btn{
  display:inline-flex; align-items:center; gap:.7em;
  font:500 var(--t-label)/1 var(--font-mono); letter-spacing:.18em; text-transform:uppercase;
  color:var(--ink); background:transparent; text-decoration:none; cursor:pointer;
  border:1px solid var(--rule); border-radius:999px; padding:14px 20px;
  transition:border-color var(--d-fast), background-color var(--d-fast), color var(--d-fast);
}
.btn:hover{ border-color:var(--ink) }
.btn--solid{ background:var(--ink); color:var(--paper); border-color:var(--ink) }
.btn--solid:hover{ background:transparent; color:var(--ink) }
.btn i{ font-style:normal; transition:transform var(--d-fast) var(--ease-out) }
.btn:hover i{ transform:translate(3px,-3px) }

.tag{
  display:inline-flex; align-items:center; gap:.5em;
  font:500 var(--t-label)/1 var(--font-mono); letter-spacing:.16em; text-transform:uppercase;
  padding:7px 10px; border:1px solid var(--rule); border-radius:4px;
}
.tag::before{ content:''; width:5px; height:5px; background:currentColor }   /* an anchor point */

.card{
  position:relative; background:var(--card);
  border:1px solid var(--rule); border-radius:10px;
  padding:clamp(20px, 2.4vw, 32px);
}

/* ---- 10. the build reveal: points, then outline, then content -------------
   Add data-build to anything with a box. upon.js adds .is-built when it comes
   into view. Four anchor points appear at the corners, the outline draws
   between them, then the content rises in. Built in the open, as UI. */
[data-build]{ position:relative; isolation:isolate }
[data-build]::before{                                 /* the four corner points */
  content:''; position:absolute; inset:-3px; pointer-events:none; z-index:2;
  background:
    linear-gradient(var(--ink), var(--ink)) top left     / 6px 6px no-repeat,
    linear-gradient(var(--ink), var(--ink)) top right    / 6px 6px no-repeat,
    linear-gradient(var(--ink), var(--ink)) bottom left  / 6px 6px no-repeat,
    linear-gradient(var(--ink), var(--ink)) bottom right / 6px 6px no-repeat;
  opacity:0; transform:scale(.96);
}
[data-build]::after{                                  /* the outline, drawn */
  content:''; position:absolute; inset:0; pointer-events:none; z-index:1;
  border:1px solid var(--ink); border-radius:inherit;
  clip-path:inset(0 100% 100% 0);
}
/* hidden start states only apply once upon.js runs (it adds .js), so a
   failed script never leaves content invisible */
.js [data-build] > *{ opacity:0; transform:translateY(14px) }

[data-build].is-built::before{
  animation:build-points 1.5s var(--ease-out) calc(var(--i, 0) * var(--stagger)) both;
}
[data-build].is-built::after{
  animation:build-outline 1.6s var(--ease-inout) calc(var(--i, 0) * var(--stagger) + .25s) both;
}
[data-build].is-built > *{
  opacity:1; transform:none;
  transition:opacity var(--d) var(--ease-out), transform var(--d-slow) var(--ease-out);
  transition-delay:calc(var(--i, 0) * var(--stagger) + .75s);
}
@keyframes build-points{
  0%  { opacity:0; transform:scale(.96) }
  18% { opacity:1; transform:scale(1) }
  70% { opacity:1 }
  100%{ opacity:0 }                                   /* the scaffold comes down */
}
@keyframes build-outline{
  0%  { clip-path:inset(0 100% 100% 0); border-color:var(--ink) }
  45% { clip-path:inset(0 0 0 0);       border-color:var(--ink) }
  100%{ clip-path:inset(0 0 0 0);       border-color:transparent }
}

/* simple rise for text that has no box */
.js [data-rise]{ opacity:0; transform:translateY(18px) }
[data-rise].is-built{
  opacity:1; transform:none;
  transition:opacity var(--d) var(--ease-out), transform var(--d-slow) var(--ease-out);
  transition-delay:calc(var(--i, 0) * var(--stagger));
}

/* ---- 11. the constructing wordmark (svg built by upon.js) ---- */
.mark{ overflow:visible }
.mark .m-guide{ stroke:var(--guide) }
.mark .m-guide-label{ fill:var(--line); font:500 11px var(--font-mono); letter-spacing:1.5px }
.mark .m-fill{ fill:var(--ink) }
.mark .m-line{ stroke:var(--ink); fill:none }
.mark .m-hnd{ stroke:var(--line) }
.mark .m-knob{ fill:var(--paper); stroke:var(--line) }
.mark .m-pt{ fill:var(--ink) }

@media (prefers-reduced-motion: reduce){
  [data-build]::before,[data-build]::after{ animation:none !important; opacity:0 }
  [data-build] > *,[data-rise]{ opacity:1 !important; transform:none !important; transition:none !important }
}
