/* tiporsub — components. Tokens live in brand.css, which must load first. */

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--text-base);
  background: var(--bg);
  color: var(--ink);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  margin: 0 0 .5em;
  font-weight: var(--weight-bold);
  letter-spacing: var(--track-display);
  line-height: 1.12;
}
h1 { font-size: var(--text-4xl); }
h2 { font-size: clamp(1.4rem, 3vw, var(--text-2xl)); }
h3 { font-size: var(--text-md); letter-spacing: var(--track-tight); }
p { margin: 0 0 1em; }
a { color: inherit; }

.muted { color: var(--ink-2); }
.dim { color: var(--ink-3); }
.small { font-size: var(--text-sm); }
.tiny { font-size: var(--text-xs); }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.hidden { display: none !important; }
/* The `hidden` attribute is only `display:none` in the UA stylesheet, so any author
   rule with an explicit display (a flex row, a grid) silently overrides it. Make the
   attribute mean what everyone assumes it means. */
[hidden] { display: none !important; }

.wrap { max-width: 1080px; margin: 0 auto; padding: 0 20px; }
.narrow { max-width: 620px; margin: 0 auto; padding: 0 20px; }

/* ------------------------------------------------------------------- buttons */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5em;
  font: inherit;
  font-weight: var(--weight-semi);
  letter-spacing: var(--track-tight);
  padding: .68em 1.2em;
  border-radius: var(--r-pill);
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  text-decoration: none;
  transition: transform var(--fast) var(--ease), box-shadow var(--fast) var(--ease),
              background var(--fast) var(--ease), border-color var(--fast) var(--ease),
              opacity var(--fast) var(--ease);
}
.btn:hover { transform: translateY(-1px); box-shadow: var(--shadow); border-color: var(--ink-3); }
.btn:active { transform: translateY(0); }
.btn:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
.btn:disabled { opacity: .45; cursor: not-allowed; transform: none; box-shadow: none; }

/* Platform actions — always jade. This is tiporsub speaking. */
.btn-primary {
  background: var(--brand);
  color: var(--brand-ink);
  border-color: transparent;
  box-shadow: var(--shadow-sm);
}
.btn-primary:hover {
  background: color-mix(in srgb, var(--brand) 88%, black);
  border-color: transparent;
  box-shadow: var(--shadow-brand);
}

/* The creator's action — their colour. This is the creator speaking. */
.btn-accent {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: transparent;
  box-shadow: var(--shadow-sm);
}
.btn-accent:hover {
  border-color: transparent;
  filter: brightness(1.04);
  box-shadow: 0 8px 24px -10px color-mix(in srgb, var(--accent) 55%, transparent);
}

.btn-ink { background: var(--ink); color: var(--bg); border-color: transparent; }
.btn-ghost { background: transparent; border-color: transparent; color: var(--ink-2); }
.btn-ghost:hover { background: var(--surface-2); box-shadow: none; border-color: transparent; color: var(--ink); }
.btn-soft { background: var(--brand-soft); color: var(--brand-soft-ink); border-color: transparent; }
.btn-lg { padding: .82em 1.7em; font-size: var(--text-md); }
.btn-sm { padding: .42em .85em; font-size: var(--text-sm); }
.btn-block { width: 100%; }
.btn-danger { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 34%, transparent); background: transparent; }
.btn-danger:hover { background: color-mix(in srgb, var(--bad) 9%, transparent); border-color: var(--bad); }

/* --------------------------------------------------------------------- forms */

label { display: block; font-weight: var(--weight-semi); font-size: var(--text-sm); margin-bottom: .4em; }
.field { margin-bottom: 1.1rem; }
.field .hint { font-size: var(--text-xs); color: var(--ink-3); margin: .4em 0 0; }

input[type=text], input[type=email], input[type=password], input[type=number], input[type=url],
select, textarea {
  width: 100%;
  font: inherit;
  color: var(--ink);
  padding: .68em .85em;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  outline: none;
  transition: border-color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
input::placeholder, textarea::placeholder { color: var(--ink-3); }
input:focus, select:focus, textarea:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 22%, transparent);
}
textarea { resize: vertical; min-height: 84px; line-height: 1.55; }

.check { display: flex; gap: .65em; align-items: flex-start; cursor: pointer; font-weight: var(--weight-body); }
.check input {
  margin-top: .28em; width: 1.1em; height: 1.1em; flex: none;
  accent-color: var(--brand);
}

.row { display: flex; gap: .85rem; flex-wrap: wrap; }
.row > * { flex: 1 1 0; min-width: 0; }

/* ------------------------------------------------- segmented control (shared)
   Used by the checkout tabs and the dashboard alignment picker. Lives here, not in
   checkout.css, because two unrelated pages need it. */
.seg {
  display: flex; gap: .25rem; padding: .28rem;
  background: var(--surface-2); border-radius: var(--r-pill); border: 1px solid var(--line);
}
.seg-btn {
  flex: 1; font: inherit; font-weight: var(--weight-semi); font-size: var(--text-sm);
  padding: .55em .9em; border: 0; border-radius: var(--r-pill);
  background: transparent; color: var(--ink-2); cursor: pointer;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.seg-btn:hover { color: var(--ink); }
.seg-btn.on { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-sm); }

/* --------------------------------------------------------------------- cards */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: 1.6rem;
  box-shadow: var(--shadow);
}
.card + .card { margin-top: 1rem; }
.card-flat { box-shadow: none; }
.card h3 { margin-bottom: .6rem; }

.pill {
  display: inline-flex; align-items: center; gap: .4em;
  font-size: var(--text-xs); font-weight: var(--weight-semi); letter-spacing: .01em;
  padding: .28em .72em; border-radius: var(--r-pill);
  background: var(--surface-2); color: var(--ink-2);
  border: 1px solid var(--line);
}
.pill-good { color: var(--brand-soft-ink); border-color: transparent; background: var(--brand-soft); }
.pill-warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 28%, transparent); background: color-mix(in srgb, var(--warn) 11%, transparent); }
.pill-bad  { color: var(--bad);  border-color: color-mix(in srgb, var(--bad) 28%, transparent);  background: color-mix(in srgb, var(--bad) 9%, transparent); }

/* -------------------------------------------------------------------- header */

.topbar {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: blur(14px) saturate(140%);
  border-bottom: 1px solid var(--line);
}
.topbar .wrap { display: flex; align-items: center; gap: .75rem; height: 66px; }
.spacer { flex: 1; }

/* On a narrow screen the signed-in nav does not fit: brand + Pricing + Admin + @handle +
   Dashboard measured 466px against a 375px viewport, which made the whole PAGE swipe
   sideways. (Logged out it fits exactly, which is why this is easy to miss.) Contain the
   overflow inside the bar instead of hiding links — every destination stays reachable, and
   the page itself stops scrolling horizontally. The scrollbar is hidden because a 3px bar
   under a 66px header reads as damage, not as an affordance. */
@media (max-width: 620px) {
  .topbar .wrap { overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none; }
  .topbar .wrap::-webkit-scrollbar { display: none; }
  .topbar .brand { flex: none; }
}

/* --------------------------------------------------------------------- misc */

.alert {
  padding: .85em 1.05em; border-radius: var(--r-md); font-size: var(--text-sm);
  border: 1px solid var(--line); background: var(--surface-2); margin-bottom: 1rem;
  line-height: 1.5;
}
.alert-bad { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 30%, transparent); background: color-mix(in srgb, var(--bad) 8%, transparent); }
.alert-good { color: var(--brand-soft-ink); border-color: transparent; background: var(--brand-soft); }

.copy-row { display: flex; gap: .5rem; align-items: stretch; }
.copy-row input, .copy-row textarea {
  font-family: var(--font-mono); font-size: var(--text-sm); background: var(--surface-2);
}

.divider { height: 1px; background: var(--line); border: 0; margin: 1.6rem 0; }

.avatar {
  width: 84px; height: 84px; border-radius: 50%;
  background: var(--surface-2); border: 3px solid var(--surface);
  display: grid; place-items: center;
  font-size: 2.4rem; line-height: 1; overflow: hidden;
  box-shadow: var(--shadow);
}
/* No emoji chosen: their initial, in their own colour. Never a stock glyph. */
.avatar.is-initial {
  font-size: 2rem; font-weight: var(--weight-bold);
  letter-spacing: 0;
  background: color-mix(in srgb, var(--accent) 22%, var(--surface-2));
  color: color-mix(in srgb, var(--accent) 78%, var(--ink));
}

table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
th {
  text-align: left; font-size: var(--text-xs); text-transform: uppercase;
  letter-spacing: var(--track-wide); color: var(--ink-3);
  font-weight: var(--weight-semi); padding: .55rem .6rem;
}
td { padding: .7rem .6rem; border-top: 1px solid var(--line); vertical-align: top; }
.table-scroll { overflow-x: auto; }

.skeleton { background: var(--surface-2); border-radius: var(--r-sm); animation: pulse 1.4s ease-in-out infinite; color: transparent; }
@keyframes pulse { 50% { opacity: .5; } }

/* A warm bloom behind hero content. Used sparingly — one per page, at the top.
   The horizontal inset is 0, not negative: bleeding it sideways made the document ~20%
   wider than the viewport, so every page with a hero had a horizontal scrollbar and swiped
   sideways on a phone. Clipping at the root does not fix it — `overflow-x: clip` on <html>
   still left the page scrollable by the overflow amount (measured), and `hidden` would turn
   the root into a scroll container and break `position: sticky` on .topbar. Containing the
   decoration is the fix. The glow is a soft gradient that already reaches both edges, so
   there is nothing visible to lose. Keep the vertical bleed — it has no scrollbar cost. */
.bloom { position: relative; }
.bloom::before {
  content: ''; position: absolute; inset: -10% 0 40%;
  background: var(--bloom); pointer-events: none; z-index: -1;
}

::selection { background: color-mix(in srgb, var(--brand) 26%, transparent); }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ---------------------------------------------------------------- long-form prose
   Terms, privacy and anything else that is mostly words. Measure is capped near 68
   characters because legal text is read carefully, and a wide line makes careful
   reading harder. Shared here rather than inlined per page so the two legal pages
   cannot drift apart. */
.legal { max-width: 46rem; margin: 0 auto; padding: 2.5rem 0 4rem; }
.legal h1 { font-size: clamp(1.7rem, 4vw, 2.3rem); margin-bottom: .4rem; }
.legal .updated { color: var(--ink-3); font-size: var(--text-sm); margin-bottom: 2rem; }
.legal h2 {
  font-size: 1.15rem; margin: 2.4rem 0 .7rem; padding-top: 1.4rem;
  border-top: 1px solid var(--line);
}
.legal h2:first-of-type { border-top: 0; padding-top: 0; }
.legal h3 { font-size: 1rem; margin: 1.5rem 0 .4rem; }
.legal p, .legal li { color: var(--ink-2); line-height: 1.7; }
.legal p { margin-bottom: .9rem; }
.legal ul, .legal ol { margin: 0 0 1rem 1.2rem; }
.legal li { margin-bottom: .45rem; }
.legal strong { color: var(--ink); font-weight: var(--weight-semi); }
.legal a { text-decoration: underline; text-underline-offset: 2px; }
.legal .toc {
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 1.1rem 1.3rem; margin-bottom: 2.5rem;
}
.legal .toc p { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: var(--track-wide); color: var(--ink-3); margin-bottom: .6rem; }
.legal .toc ol { columns: 2; column-gap: 2rem; margin: 0 0 0 1.1rem; }
@media (max-width: 560px) { .legal .toc ol { columns: 1; } }
.legal .toc li { margin-bottom: .3rem; font-size: var(--text-sm); }

/* A `.legal .fillme` rule lived here to flag unfilled placeholders in the legal pages in
   loud apricot. The operator details are now filled in, so it is gone rather than left as
   dead CSS on every page. If you ever draft legal copy with gaps again, make the marker
   impossible to miss — a subtle placeholder is one that ships. */
