/* =============================================================
   barakahgames.com — page composition

   Composes from tokens.css only. No hex values live here and no
   token is redefined here: tokens.css is duplicated verbatim into
   the invite-site repo and the Shopify theme, so editing it in one
   place silently diverges the others.

   The @font-face blocks are the one exception that has to live
   here. The family NAMES are shared brand tokens; the font FILES
   cannot be, because Shopify serves its assets through asset_url.
   Only the names travel between repos.
   ============================================================= */

/* ---------- Faces ----------
   Subset from the exact TTFs the app ships (@expo-google-fonts) so
   the two products render identical letterforms. Copied from the
   invite site rather than re-subset, so all three surfaces are
   byte-identical. Both faces are SIL OFL; the licences ship beside
   the files in /fonts. */

@font-face {
  font-family: "Playfair Display";
  src: url("/fonts/playfair-display-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Montserrat";
  src: url("/fonts/montserrat-300.woff2") format("woff2");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

/* Weight 400 exists only for the letterspaced uppercase controls —
   the app's action label is bodyRegular, not bodyLight. Subset to
   uppercase, digits, space and a full stop. */
@font-face {
  font-family: "Montserrat";
  src: url("/fonts/montserrat-400-upper.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* ---------- Ground ---------- */

html {
  min-height: 100%;
}

body {
  min-height: 100vh;
  padding: var(--bg-space-xl) var(--bg-space-md);
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}

/* The one-screen pages centre their single column. The document
   pages do not — a policy that centres vertically jumps on load. */
body.screen {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

main {
  width: 100%;
  max-width: var(--bg-measure);
  margin: 0 auto;
}

/* Documents run wider than the body measure only for their rules and
   headings; paragraphs stay at --bg-measure via the token base. */
main.document {
  max-width: 42rem;
}

/* ---------- The terracotta line ----------
   The same curve as components/TerracottaLine.tsx, not a redraw: the
   app's Catmull-Rom control points converted to cubic Béziers, which
   is exact for tension 0.5. Taken from the invite site, which did the
   conversion. preserveAspectRatio="none" reproduces the app's
   independent width/height scaling, and non-scaling-stroke keeps the
   weight at the app's 1.6 regardless of the box. */

.line {
  display: block;
  width: 100%;
  height: clamp(2.25rem, 11vw, 3.5rem);
  margin: 0 auto var(--bg-space-lg);
  overflow: visible;
}

.line path {
  fill: none;
  stroke: var(--p-accent);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  /* pathLength="1" normalises the dash maths, so the draw-on needs
     no measured length. */
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: line-draw calc(var(--bg-motion-duration) * 2.5)
    var(--bg-motion-ease) both;
}

@keyframes line-draw {
  to {
    stroke-dashoffset: 0;
  }
}

/* ---------- Copy ---------- */

.eyebrow {
  margin: 0 0 var(--bg-space-md);
}

.lede {
  color: var(--p-text-body);
  font-size: var(--bg-size-body-lg);
}

.hint {
  color: var(--p-text-hint);
  font-size: var(--bg-size-small);
}

/* ---------- Entry motion ----------
   Fade and rise. The stagger is the only sequencing on any page;
   tokens.css already collapses the duration under reduced-motion,
   so the delays below become inaudible rather than needing a
   second media query. */

.enter-1 { animation-delay: 0ms; }
.enter-2 { animation-delay: 90ms; }
.enter-3 { animation-delay: 180ms; }
.enter-4 { animation-delay: 270ms; }
.enter-5 { animation-delay: 360ms; }
.enter-6 { animation-delay: 450ms; }

@media (prefers-reduced-motion: reduce) {
  .enter-1, .enter-2, .enter-3,
  .enter-4, .enter-5, .enter-6 {
    animation-delay: 0ms;
  }
}

/* ---------- Fields ----------
   tokens.css supplies .field itself — transparent, one underline,
   terracotta on focus. What it cannot supply is the pairing with a
   permanent label above, which is the part the app is strict about. */

.field-group {
  margin: 0 0 var(--bg-space-lg);
}

.field-label {
  display: block;
  margin: 0 0 var(--bg-space-xs);
  font-family: var(--bg-font-body);
  font-size: var(--bg-size-label);
  font-weight: var(--bg-weight-secondary);
  letter-spacing: var(--bg-tracking-label);
  text-transform: uppercase;
  /* Deliberately NOT .label — these are not the gold ones. Gold is
     rationed to the eyebrow above a headline and to Ramadan. */
  color: var(--p-text-label);
}

.field {
  display: block;
  width: 100%;
  font-size: var(--bg-size-body);
}

textarea.field {
  min-height: 7rem;
  resize: vertical;
}

/* Autofill repaints the field white in WebKit and Blink, which is
   the one thing the brand cannot have. There is no way to set the
   background directly, so the fill is pushed outside the paint box
   by a long inset shadow and the text is drawn by the caret colour. */
.field:-webkit-autofill,
.field:-webkit-autofill:hover,
.field:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--p-text);
  -webkit-box-shadow: 0 0 0 100px var(--p-ground) inset;
  caret-color: var(--p-text);
}

/* ---------- The action ----------
   A letterspaced uppercase label beside a circular outlined arrow.
   No fills anywhere: --bg-fill-permitted is 0 and stays 0. */

.action {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  padding: 0;
  border: 0;
  background: none;
  border-radius: var(--bg-radius-none);
  text-decoration: none;
  color: var(--p-text);
  cursor: pointer;
  transition: opacity var(--bg-motion-duration-fast) var(--bg-motion-ease);
}

.action:hover,
.action:active {
  opacity: 0.75;
}

.action[disabled] {
  opacity: 0.45;
  cursor: default;
}

.action__label {
  font-family: var(--bg-font-body);
  font-weight: var(--bg-weight-body);
  font-size: 0.625rem;
  letter-spacing: 0.3em;
  /* The tracking adds a trailing space after the last letter;
     pulling it back keeps the optical gap to the circle at 14. */
  margin-right: -0.3em;
  text-transform: uppercase;
  white-space: nowrap;
}

.action__circle {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: var(--bg-hairline-width) solid
    rgb(from var(--p-ink) r g b / 0.35);
  border-radius: var(--bg-radius-full);
}

.action__circle svg {
  display: block;
  width: 18px;
  height: 18px;
  fill: none;
  stroke: var(--p-ink);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@supports not (color: rgb(from #fff r g b / 50%)) {
  .action__circle {
    border-color: var(--p-hairline);
  }
}

/* ---------- Form states ----------
   Three states, one at a time. The success state replaces the form
   rather than sitting beneath it — the app never stacks a result
   under the control that produced it. */

.form-state[hidden] {
  display: none;
}

.form-error {
  margin: var(--bg-space-md) 0 0;
  color: var(--p-accent);
  font-size: var(--bg-size-small);
}

/* The honeypot. Off-screen rather than display:none, which some
   autofillers skip and some bots detect. */
.trap {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- Documents ----------
   /privacy and /terms. Long-form, read once, usually by a reviewer
   or by someone who is worried. Generous leading, hairline rules
   instead of boxes, and no rectangle anywhere. */

.document h1 {
  margin-bottom: var(--bg-space-lg);
}

.document h2 {
  font-size: var(--bg-size-display-3);
  margin-top: var(--bg-space-xl);
  padding-top: var(--bg-space-md);
  border-top: var(--bg-hairline-width) solid var(--p-hairline);
}

.document h3 {
  font-size: var(--bg-size-body-lg);
  font-family: var(--bg-font-body);
  font-weight: var(--bg-weight-body);
  margin-top: var(--bg-space-lg);
  margin-bottom: var(--bg-space-xs);
  letter-spacing: 0;
}

.document p,
.document li {
  color: var(--p-text-body);
}

.document ul {
  margin: 0 0 var(--bg-space-md);
  padding-left: 1.1rem;
  max-width: var(--bg-measure);
}

.document li {
  margin-bottom: var(--bg-space-xs);
}

.document li::marker {
  color: var(--p-text-hint);
}

.document strong {
  color: var(--p-text);
  font-weight: var(--bg-weight-body);
}

.document a {
  color: var(--p-text);
  text-decoration-color: var(--p-hairline);
  text-underline-offset: 0.2em;
}

.document a:hover {
  text-decoration-color: var(--p-accent);
}

.updated {
  color: var(--p-text-hint);
  font-size: var(--bg-size-small);
  margin-bottom: var(--bg-space-xl);
}

/* Tables — the subprocessor list. Hairline rules only, and it has to
   survive a phone without a horizontal scrollbar on the page itself. */
.table-scroll {
  overflow-x: auto;
  margin: 0 0 var(--bg-space-md);
}

.document table {
  border-collapse: collapse;
  width: 100%;
  min-width: 30rem;
  font-size: var(--bg-size-small);
}

.document th,
.document td {
  text-align: left;
  vertical-align: top;
  padding: var(--bg-space-sm) var(--bg-space-md) var(--bg-space-sm) 0;
  border-bottom: var(--bg-hairline-width) solid var(--p-hairline);
  color: var(--p-text-body);
}

.document th {
  color: var(--p-text-label);
  font-weight: var(--bg-weight-secondary);
  font-size: var(--bg-size-label);
  letter-spacing: var(--bg-tracking-label);
  text-transform: uppercase;
  white-space: nowrap;
}

/* ---------- Footer ----------
   One hairline row. It exists because an email is collected on / and
   a reviewer follows these two links out of the app. */

.footer {
  width: 100%;
  max-width: var(--bg-measure);
  margin: var(--bg-space-2xl) auto 0;
  padding-top: var(--bg-space-md);
  border-top: var(--bg-hairline-width) solid var(--p-hairline);
  display: flex;
  flex-wrap: wrap;
  gap: var(--bg-space-md);
  font-size: var(--bg-size-small);
}

.document + .footer {
  max-width: 42rem;
}

.footer a {
  color: var(--p-text-hint);
  text-decoration: none;
}

.footer a:hover {
  color: var(--p-text-body);
}

.footer__mark {
  margin-left: auto;
  color: var(--p-text-hint);
}

/* ---------- Choice rows ----------
   A native <select> renders OS chrome, which on most platforms means
   a white sheet — the one thing the brand cannot have. The app uses
   hairline-ruled rows for every choice list, so the form does too.
   tokens.css supplies .row; this is the radio pairing. */

/* A fieldset carries a default border, padding and min-width that all
   have to go. min-width:0 is the one that is easy to miss — without
   it a fieldset refuses to shrink below its content on narrow
   screens. */
.choices {
  border: 0;
  padding: 0;
  margin: 0 0 var(--bg-space-lg);
  min-width: 0;
}

/* A legend is not a normal box — it renders into the fieldset border
   in most engines and ignores much of what is set on it. Making it a
   plain block is the reliable way to flow it like the field labels
   above the other inputs, which is what it has to match. */
.choices legend {
  display: block;
  float: none;
  width: 100%;
  padding: 0;
  margin: 0 0 var(--bg-space-xs);
  font-family: var(--bg-font-body);
  font-size: var(--bg-size-label);
  font-weight: var(--bg-weight-secondary);
  letter-spacing: var(--bg-tracking-label);
  text-transform: uppercase;
  color: var(--p-text-label);
}

.choices__set {
  border-top: var(--bg-hairline-width) solid var(--p-hairline);
}

.choice {
  /* The visually-hidden input is positioned against this, so the row
     has to establish the containing block. Without it the input
     escapes to the page. */
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--bg-space-sm);
  cursor: pointer;
  color: var(--p-text-body);
  font-size: var(--bg-size-body);
}

.choice input {
  /* The native control is removed rather than restyled — appearance
     is unreliable across engines and a partly-styled radio is worse
     than a drawn one. It stays in the accessibility tree. */
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  pointer-events: none;
}

.choice__mark {
  flex: none;
  width: 18px;
  height: 18px;
  border: var(--bg-hairline-width) solid var(--p-hairline);
  border-radius: var(--bg-radius-full);
  display: grid;
  place-items: center;
}

/* The selected dot. This is a mark rather than a control, which is
   the same exemption the camera shutter and the seal have in the app. */
.choice__mark::after {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: var(--bg-radius-full);
  background: var(--p-accent);
  opacity: 0;
  transition: opacity var(--bg-motion-duration-fast) var(--bg-motion-ease);
}

.choice input:checked + .choice__mark::after {
  opacity: 1;
}

.choice input:checked + .choice__mark {
  border-color: var(--p-accent);
}

.choice input:focus-visible + .choice__mark {
  outline: 2px solid var(--p-accent);
  outline-offset: 3px;
}
