/* Accio · coming soon. A Bidri ground, the wordmark inlaid in silver, the objects set down one by one. */

@font-face {
  font-family: 'Accio Sans';
  src: url('fonts/AccioSans.woff2') format('woff2');
  font-weight: 200 900;
  font-stretch: 100% 105%;
  font-display: swap;
}

:root {
  --oxide: #131210;
  --parchment: #f0ebe7;
  --muted: rgba(240, 235, 231, 0.78);
  --sans: 'Accio Sans', system-ui, sans-serif;
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }
html { background: var(--oxide) url('textures/alloy-ground.webp') repeat; background-size: 1024px; }
body {
  margin: 0; min-height: 100dvh; color: var(--parchment);
  font-family: var(--sans); font-stretch: 105%; font-weight: 350; letter-spacing: 0.02em;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
}
/* Where the oil pooled: the edges of the slab sit a shade deeper. */
body::before {
  content: ''; position: fixed; inset: 0; pointer-events: none;
  background: radial-gradient(120% 90% at 50% 45%, transparent 40%, rgba(0, 0, 0, 0.5) 100%);
}
p, h1 { margin: 0; }

/* Highlighting is Kasuti: madder thread on white cloth, with a running stitch along the edge.
   main.js paints the cloth and stitch on a fixed canvas behind the text; without it, the browser's
   own highlight takes the cloth and thread colours. */
::selection {
  background: #ffffff; color: #512026; text-shadow: none;
  text-decoration: underline dashed #512026; text-decoration-thickness: 1.5px; text-underline-offset: 0.22em;
}
.has-stitches ::selection { background: transparent; text-decoration: none; }
.has-stitches .well input::selection { background: #ffffff; color: #512026; }
.stitches { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; }

/* Only words can be selected. The empty slab between them can't: dragging past the end of a line
   would otherwise make the browser jump the selection to whatever text comes next in the page. */
.stage, .group, .mark, .showcase, .updates, .reveal { -webkit-user-select: none; user-select: none; }
.gloss, .about, .updates-label, .scramble-text, .updates-status, .well input { -webkit-user-select: text; user-select: text; }
/* Each piece of text has an invisible margin to grab, so starting or ending a drag a little past the
   words still lands on that line. Padding and an equal negative margin: nothing moves. */
.gloss { padding: 10px 32px; margin: -10px -32px; }
.updates-label { padding: 10px 16px; margin: -10px -16px; display: inline-block; }
@media (min-width: 1000px) { .about { padding: 8px 140px 8px 0; } }
/* The objects and the inlay are things on the slab, not text: they can't be selected or dragged. */
.objects, .object, .logo svg { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; -webkit-user-drag: none; }

.stage { position: relative; z-index: 1; min-height: 100dvh; display: grid; place-items: center; padding: 48px 16px; }
.group { display: grid; justify-items: center; gap: clamp(44px, 9vh, 96px); width: min(560px, 100%); }

/* The name: one gloss ends at the wordmark's top-left corner, the other starts at its bottom-right. */
.mark { position: relative; width: clamp(128px, 36vw, 156px); }
.logo { width: 100%; line-height: 0; }
.logo svg { display: block; width: 100%; height: auto; overflow: visible; }
.gloss { position: absolute; font-size: 13px; line-height: 1; color: var(--muted); white-space: nowrap; }
.gloss-before { right: 100%; top: -0.15em; }
.gloss-after { left: 100%; bottom: -0.55em; }

/* The objects: one at a time, each replacing the last. */
.objects { position: relative; width: clamp(160px, 48vw, 220px); aspect-ratio: 1; }
.object {
  position: absolute; inset: 0; margin: auto; display: block;
  max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain;
  visibility: hidden;
  filter: drop-shadow(4px 10px 9px rgba(0, 0, 0, 0.6));
}
.object.is-on { visibility: visible; }

/* What Accio is. Wide screens: a column of single words out at the left margin, level with the object,
   set with no width at all, so every word breaks onto its own line. Narrower: a short paragraph under the object. */
.showcase { display: grid; justify-items: center; gap: 28px; }
.about { order: 1; max-width: 27ch; font-size: 15px; line-height: 1.35; font-weight: 380; letter-spacing: 0.01em; text-align: center; color: var(--muted); }
@media (min-width: 1000px) {
  .showcase { position: relative; display: block; }
  .about {
    position: absolute; top: 50%; transform: translateY(-50%);
    left: calc(clamp(24px, 9.6vw, 240px) - 50vw + 50%);
    width: 0; max-width: none; font-size: 17px; line-height: 1.2; text-align: left; color: var(--parchment);
  }
}

/* The letter: "coming soon" becomes "get updates", and a Bidri silver frame fades in with the email field.
   Wide screens: the words keep their place under the object and the frame hangs off to their right.
   Narrower screens: the frame appears below, centred. */
.updates { --fw: min(calc(100vw - 32px), 380px); --fh: calc(var(--fw) * 300 / 1400); display: grid; justify-items: center; width: 100%; }
.updates-label { font-size: 17px; line-height: 1.2; font-weight: 380; letter-spacing: 0.01em; cursor: default; }
/* The room is the settled words, invisible, holding the label's size; the noise plays on top of it,
   so nothing beside the label moves while the letters scramble. */
.scramble { position: relative; display: inline-block; white-space: nowrap; }
.scramble-room { visibility: hidden; -webkit-user-select: none; user-select: none; }
.scramble-text { position: absolute; left: 0; top: 0; }
.reveal { display: grid; justify-items: center; margin-top: 12px; }
/* Once "get updates" settles, the frame surfaces: a slow fade and the smallest rise, nothing more. */
.reveal { opacity: 0; transform: translateY(4px); transition: opacity 1200ms cubic-bezier(0.25, 0.1, 0.25, 1), transform 1200ms cubic-bezier(0.16, 1, 0.3, 1); }
.updates.is-open .reveal { opacity: 1; transform: none; }
.frame { width: var(--fw); height: var(--fh); }
.frame-inner { position: relative; width: var(--fw); height: 100%; background: url('brand/updates-frame.webp') left center / 100% 100% no-repeat; }
/* Messages come on a slip of parchment set square under the frame, its edges run with the same madder stitch
   as the highlight. The space is kept when there's nothing to say, so the page never jumps. */
.updates-status {
  --thread: #512026; --run: 4px; --gap: 3px;
  justify-self: center; width: fit-content; max-width: 100%; min-height: calc(1.3em + 16px); margin-top: 10px; padding: 8px 14px;
  font-size: 13px; line-height: 1.3; color: #131210; text-align: center;
  background-color: var(--parchment);
  background-image:
    repeating-linear-gradient(90deg, var(--thread) 0 var(--run), transparent var(--run) calc(var(--run) + var(--gap))),
    repeating-linear-gradient(90deg, var(--thread) 0 var(--run), transparent var(--run) calc(var(--run) + var(--gap)));
  background-size: calc(100% - 8px) 1.5px, calc(100% - 8px) 1.5px;
  background-position: 4px 3px, 4px calc(100% - 3px);
  background-repeat: no-repeat;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.4) inset, 0 3px 8px rgba(0, 0, 0, 0.55);
}
.updates-status:empty { visibility: hidden; }
.updates-status[data-tone='error'] { color: #512026; }
@media (prefers-reduced-motion: no-preference) {
  .updates-status.is-new { animation: slip 520ms cubic-bezier(0.34, 1.4, 0.64, 1) both; }
  @keyframes slip { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
}

@media (min-width: 1000px) {
  .updates { --fw: 420px; display: block; position: relative; width: auto; justify-self: center; }
  .updates-label br { display: inline; }
  .reveal { position: absolute; left: calc(100% + 18px); top: calc(50% - var(--fh) / 2); justify-items: start; margin-top: 0; }
  .updates-status { justify-self: start; margin-left: 7%; text-align: left; }
}

/* The well is the recessed black panel inside the frame, measured from the artwork. */
.well { position: absolute; left: 7.2%; right: 7.4%; top: 31.4%; bottom: 33.9%; display: flex; align-items: center; gap: 6px; padding: 0 1.2% 0 3%; border-radius: 1px; }
.well:focus-within { box-shadow: inset 0 0 0 1px rgba(240, 235, 231, 0.35); }
.well input[type='email'] {
  flex: 1; min-width: 0; height: 100%; padding: 0; border: 0; background: transparent; color: var(--parchment);
  font: inherit; font-size: clamp(14px, 3.6vw, 16px); letter-spacing: 0.02em; outline: none; caret-color: var(--parchment);
}
.well input::placeholder { color: rgba(240, 235, 231, 0.48); }
/* Autofill: browsers paint a filled-in address on their own blue. Keep it parchment on the well:
   the text colour is set directly, and the background change is delayed so long it never happens. */
.well input:-webkit-autofill,
.well input:-webkit-autofill:hover,
.well input:-webkit-autofill:focus,
.well input:autofill {
  -webkit-text-fill-color: var(--parchment);
  caret-color: var(--parchment);
  -webkit-box-shadow: 0 0 0 1000px transparent inset;
  transition: background-color 600000s 0s, color 600000s 0s;
}
/* The button is a tablet of mother-of-pearl set in a thin silver bezel, like the card case's lid.
   Pointing at it tilts it to the light: the nacre slides under a fixed sheen. */
.well button {
  flex: none; position: relative; display: grid; place-items: center; height: 74%; aspect-ratio: 1.5; padding: 0; border: 0; border-radius: 3px;
  background: url('brand/pearl.webp') 10% 20% / 180% auto no-repeat #e8e3da; color: #512026; cursor: pointer;
  box-shadow:
    0 0 0 1px #d4cfc7, 0 0 0 2px #6d6862, 0 1px 3px 2px rgba(0, 0, 0, 0.55),
    inset 0 1px 0 rgba(255, 255, 255, 0.85), inset 0 -2px 4px rgba(70, 58, 50, 0.32);
  transition: background-position 700ms cubic-bezier(0.16, 1, 0.3, 1), transform 160ms ease;
}
.well button::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(160deg, rgba(255, 255, 255, 0.35), rgba(255, 255, 255, 0) 45%, rgba(60, 50, 44, 0.18));
}
.well button svg { position: relative; }
.well button:hover { background-position: 90% 80%; }
.well button:active { transform: scale(0.96); }
.well button:focus-visible { outline: 2px solid var(--parchment); outline-offset: 2px; }
.well button:disabled { opacity: 0.6; cursor: default; }
.well svg { width: 54%; height: auto; overflow: visible; }
.trap { position: absolute; left: -10000px; width: 1px; height: 1px; opacity: 0; }
.updates.is-done .well input[type='email'] { color: var(--parchment); }

.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* Before the inlay is cut, the letters wait in flat parchment so nothing jumps. */
#letters { fill: var(--parchment); }
.is-inlaid #letters { fill: #fff; }
@media (prefers-reduced-motion: reduce) { .reveal { transition: none; transform: none; } }
@media (max-width: 999px) { .updates-label br { display: none; } }
@media (prefers-reduced-motion: no-preference) {
  .is-inlaid .logo svg { animation: rise 1100ms cubic-bezier(0.16, 1, 0.3, 1) both; }
  @keyframes rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
}

/* Phones: the glosses sit above and below the name instead of beside it. */
@media (max-width: 460px) {
  .gloss { position: static; display: block; font-size: 11.5px; }
  .gloss-before { margin-bottom: 8px; }
  .gloss-after { margin-top: 8px; text-align: right; }
  .mark { width: min(70vw, 240px); }
}
