/* Trader in a Box teaser (traderinabox.com until the full page is finished).
   One centred logo on a dark field: the box (logo D, "lid ajar") draws itself, then breathes as a
   dark silhouette, a cameo: gold light leaking from under its floating lid pulses gently, the glow
   behind it is almost off (--glow-rest). Opening it (hover or a tap: teaser.js puts the class "open"
   on the stage) brings the glow up, lights the box, floats it a little higher while it keeps bobbing,
   and lifts the lid: candles form and scroll through the box like a live chart, drawn by teaser.js
   (the CSP allows no inline style or script). Left alone it settles back, slower than it opened.
   Brand rule: the product name is gold (--brand); no other text exists here.
   The font is self-hosted from ./fonts (SIL Open Font License 1.1, licence alongside). */

@font-face {
  font-family: "Bricolage Grotesque";
  font-style: normal;
  font-weight: 500 800;
  font-stretch: 100%;
  font-display: swap;
  src: url("fonts/bricolage-grotesque-var-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* dark on purpose, in both colour schemes: the colours are the landing page's dark theme */
:root {
  color-scheme: dark;
  --night: #07090e;
  --paper: #0c111a;
  --face: #101724;
  --face-dim: #0c1220;
  --face-lit: #151e2e;
  --edge: #3b475b;
  /* at rest the box is a silhouette: faces darker than the ground, outline barely there, the inner
     edges fainter still */
  --shade: #05070b;
  --edge-rest: #111824;
  --inner-rest: 0.3;
  --rule: #253043;
  --accent: #e3a83a;
  --brand: #f2c063;
  --pulse: 6s;
  /* the gold glow behind the box: 2 % at rest, full only while it is open */
  --glow-rest: 0.02;
  /* how far the lid lifts and the open box floats, how long one breath takes, how fast the box
     lights up (--wake) and how slowly it settles back into the silhouette (--settle) */
  --lift: -10px;
  --float: -2.5px;
  --breath: 5s;
  --wake: 0.8s;
  --settle: 1.8s;
}

* { box-sizing: border-box; }

html { height: 100%; background: var(--night); }

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right))
           max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  background: radial-gradient(ellipse 80% 70% at 50% 45%, var(--paper) 0%, var(--night) 75%);
  color: var(--brand);
  font-family: "Bricolage Grotesque", system-ui, sans-serif;
  overflow: hidden;
}

/* the landing page's chart paper, fading out towards the edges */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(color-mix(in srgb, var(--rule) 55%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--rule) 55%, transparent) 1px, transparent 1px);
  background-size: 32px 32px;
  background-position: center;
  -webkit-mask-image: radial-gradient(circle at 50% 45%, #000 0, transparent 46vmax);
  mask-image: radial-gradient(circle at 50% 45%, #000 0, transparent 46vmax);
  opacity: 0;
  animation: fade-in 3s ease-out 0.4s forwards;
}

.stage {
  position: relative;
  display: grid;
  justify-items: center;
  gap: clamp(10px, 2.5vmin, 20px);
  /* a tap opens the box: no grey flash over it on a phone */
  -webkit-tap-highlight-color: transparent;
}

.box {
  width: clamp(150px, 40vmin, 280px);
  height: auto;
  overflow: visible;
}

/* ---- the box ----
   Animations run on inner elements and the open change on an outer group (or another property),
   because a running animation overrides a class style on the same property. Each transition here is
   the way back to the silhouette (--settle); `.stage.open` below sets the quicker way in. */
.halo-wrap { opacity: var(--glow-rest); transition: opacity var(--settle) ease-in-out; }
.halo {
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  animation: breathe var(--pulse) ease-in-out 2.6s infinite;
}
.floor-wrap {
  transform-box: fill-box;
  transform-origin: center;
  transition: transform var(--settle) ease-in-out, opacity var(--settle) ease-in-out;
}
.floor {
  fill: #000;
  opacity: 0;
  filter: blur(1px);
  transform-box: fill-box;
  transform-origin: center;
  animation: fade-to-half 2s ease-out 1.6s forwards, shadow var(--breath) ease-in-out 3s infinite;
}
/* open, the whole box floats a little higher (the breathing goes on, so it bobs up there) */
.float { transition: transform var(--settle) ease-in-out; }
/* the gentle up and down, always; the floor shadow shrinks as the box rises */
.breath { animation: breath var(--breath) ease-in-out 3s infinite; }
.face { opacity: 0; fill: var(--shade); transition: fill var(--settle) ease-in-out; animation: fade-in 1.4s ease-out 1.8s forwards; }
.edge {
  fill: none;
  stroke: var(--edge-rest);
  transition: stroke var(--settle) ease-in-out, opacity var(--settle) ease-in-out;
  stroke-width: 0.5;
  stroke-linejoin: round;
  stroke-linecap: round;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  animation: draw 2.2s cubic-bezier(0.6, 0, 0.3, 1) 0.3s forwards;
}
.edge.inner { opacity: var(--inner-rest); animation-delay: 1.1s; }

/* the light inside, seen between the box and its lid: a dim gentle pulse at rest, bright open */
.light-wrap { opacity: 0.45; transition: opacity var(--settle) ease-in-out; }
.light {
  opacity: 0;
  filter: drop-shadow(0 0 1.5px var(--accent)) drop-shadow(0 0 5px var(--accent));
  animation: glow var(--pulse) ease-in-out 2.4s infinite;
}

.lid { transition: transform var(--settle) cubic-bezier(0.45, 0, 0.25, 1); }

/* ---- the candles, shown while the lid is up ----
   teaser.js draws them like a trading platform: the newest, on the right, starts as a line and its
   body builds up or down with the price; when its time is up it is fixed and the chart scrolls on.
   One colour (the brand allows no green or red): a candle that closed up is hollow, down is filled.
   The dark and the gold row are the same candles: dark over the light, gold above the back rim. */
.tape { opacity: 0; transition: opacity 0.5s ease-out; }
.tape path { fill: none; stroke-width: 0.5; stroke-linecap: round; }
.tape rect { stroke-width: 0.5; }
.tape rect.up { fill: none; }
.tape.dark path, .tape.dark rect { stroke: var(--night); }
.tape.dark rect.down { fill: var(--night); }
.tape.gold path, .tape.gold rect { stroke: var(--brand); }
.tape.gold rect.down { fill: var(--brand); }

/* ---- open (teaser.js, on hover or a tap): wake up, float, lift the lid ---- */
.stage.open .halo-wrap, .stage.open .light-wrap { opacity: 1; transition-duration: var(--wake); }
.stage.open .face { transition-duration: var(--wake); }
.stage.open .face.left, .stage.open .face.band { fill: var(--face); }
.stage.open .face.right { fill: var(--face-dim); }
.stage.open .face.top { fill: var(--face-lit); }
.stage.open .edge { stroke: var(--edge); opacity: 1; transition-duration: var(--wake); }
.stage.open .float { transform: translateY(var(--float)); transition: transform 1.4s cubic-bezier(0.3, 0, 0.2, 1); }
.stage.open .floor-wrap { transform: scale(0.88); opacity: 0.7; transition-duration: 1.4s; }
.stage.open .lid { transform: translateY(var(--lift)); transition: transform 0.9s cubic-bezier(0.2, 0.7, 0.2, 1); }
.stage.open .tape { opacity: 1; transition-delay: 0.25s; }

/* ---- the name ---- */
.name {
  margin: 0;
  font-weight: 800;
  font-size: clamp(1.35rem, 4.4vmin, 2.25rem);
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--brand);
  white-space: nowrap;
  opacity: 0;
  animation: name-in 1.8s cubic-bezier(0.2, 0.7, 0.2, 1) 3.1s forwards;
}

@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes fade-in { to { opacity: 1; } }
@keyframes fade-to-half { to { opacity: 0.55; } }
@keyframes glow {
  0%, 100% { opacity: 0.55; }
  50% { opacity: 1; }
}
@keyframes breathe {
  0%, 100% { opacity: 0.25; transform: scale(0.9); }
  50% { opacity: 0.85; transform: scale(1.05); }
}
@keyframes breath {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-1.4px); }
}
@keyframes shadow {
  0%, 100% { transform: scaleX(1); }
  50% { transform: scaleX(0.86); }
}
@keyframes name-in {
  from { opacity: 0; letter-spacing: 0.22em; filter: blur(4px); }
  to { opacity: 1; letter-spacing: -0.01em; filter: blur(0); }
}

/* no motion wanted: the still end state, the silhouette; opening still lights it and lifts the lid,
   without floating and without candles (teaser.js runs no chart either) */
@media (prefers-reduced-motion: reduce) {
  *, *::before { animation: none !important; transition: none !important; }
  body::before { opacity: 1; }
  .edge { stroke-dashoffset: 0; }
  .face { opacity: 1; }
  .floor { opacity: 0.55; }
  .halo { opacity: 0.6; }
  .light { opacity: 0.8; }
  .stage.open .float, .stage.open .floor-wrap { transform: none; }
  .stage.open .tape { opacity: 0; }
  .name { opacity: 1; }
}
