/* The Smarty pages: the wiki, the journal, the profile, the legal pages.
 *
 * Not the reading flow — that is React and Framer Motion and lives in
 * front_dev/react. This file dresses the pages that are text, and it is
 * deliberately small: the wiki is the SEO surface and should be the fastest
 * thing on the site.
 *
 * Colours mirror theme.palette in app/zygote.json. They are duplicated here
 * because a stylesheet is static and the Zygote is not — when they disagree,
 * the Zygote is right and this file is stale. Anything that must follow the
 * edition exactly reads it from $THEME in the template instead.
 */

:root {
  --t-ink: #0d0b09;
  --t-table: #1a1410;
  --t-candle: #e8b661;
  --t-brass: #a8823c;
  --t-parchment: #e6dcc6;
  --t-muted: #8a7f6d;
  --t-accent: #6b2f2f;

  --t-measure: 68ch;
  --t-gap: 1.5rem;

  /* The site is dark everywhere, and this is what tells the browser so: the
     controls it draws itself — checkboxes, the scrollbar, the file picker,
     the autofill dropdown — follow it. Without it a checkbox is a white square
     on a candlelit table. */
  color-scheme: dark;
}

* { box-sizing: border-box; }

body.t-page {
  margin: 0;
  background: var(--t-table);
  color: var(--t-parchment);
  font-family: var(--t-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

.t-wrap {
  width: 100%;
  max-width: 72rem;
  margin: 0 auto;
  padding: 0 1.25rem;
}

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

.t-header {
  border-bottom: 1px solid rgba(168, 130, 60, 0.25);
  padding: 1rem 0;
}
.t-header .t-wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--t-gap);
  flex-wrap: wrap;
}
.t-brand {
  font-family: var(--t-display);
  font-size: 1.375rem;
  letter-spacing: 0.02em;
  color: var(--t-parchment);
  text-decoration: none;
}
.t-nav {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  font-family: var(--t-ui);
  font-size: 0.9375rem;
}
.t-nav a { color: var(--t-muted); text-decoration: none; }
.t-nav a:hover { color: var(--t-parchment); }
.t-nav .t-cta {
  color: var(--t-table);
  background: var(--t-candle);
  padding: 0.4rem 0.9rem;
  border-radius: 2px;
}
.t-nav .t-cta:hover { color: var(--t-table); background: #f0c477; }

/* ---- body ---- */

.t-main { padding: 2.5rem 0 4rem; }

.longtext { max-width: var(--t-measure); }
.longtext h1 {
  font-family: var(--t-display);
  font-weight: 400;
  font-size: clamp(1.9rem, 5vw, 2.6rem);
  line-height: 1.15;
  margin: 0 0 1.5rem;
}
.longtext h3 {
  font-family: var(--t-display);
  font-weight: 400;
  font-size: 1.3rem;
  color: var(--t-candle);
  margin: 2.25rem 0 0.6rem;
}
.longtext p, .longtext li { margin: 0 0 1rem; }
.longtext a { color: var(--t-candle); }
.longtext strong { color: #fff; font-weight: 600; }

/* The fan of cards under the button. Full width of .t-ask-inner, which is the
   width of the question box above it — they line up because they share a
   container, not because a number was matched by hand. */
.t-ask-fan {
  display: block;
  width: 100%;
  height: auto;
  margin: 1.5rem auto 0;
  opacity: 0.92;
  filter: drop-shadow(0 0.6rem 1.6rem rgba(0, 0, 0, 0.55));
}

/* ---- the wordmark ---- */

.t-wordmark {
  display: block;
  width: min(20rem, 78%);
  height: auto;
  margin: 0 auto;
  /* Gold leaf on a photograph of a dark room needs its own shadow to sit on,
     or it competes with whatever detail happens to be behind it — and across
     ten scenes, something always is. */
  filter: drop-shadow(0 0.15rem 1.6rem rgba(0, 0, 0, 0.9));
}
.t-brand { display: inline-flex; align-items: center; gap: 0.55rem; }
.t-brand-mark { display: block; width: 1.9rem; height: 1.9rem; }

/* ---- the backdrop ----

   Ten candlelit rooms, one at a time, changed every ten minutes. See
   app/zygote.json (theme.backdrops) for the list and App\Handlers\Backdrop for
   which one is showing.

   It sits behind everything the reading flow draws, dimmed by the layer that
   was already there: .t-ask::before and .t-reveal::before paint the candle
   glow, and under `t-has-backdrop` they stop painting the solid table colour
   and paint a scrim instead. Legibility comes first — the room is furniture
   for the question, not the other way round. */

.t-backdrop {
  position: fixed;
  inset: 0;
  z-index: -3;
  overflow: hidden;
  background: var(--t-ink);
}
.t-backdrop-layer {
  position: absolute;
  inset: 0;
  display: block;
  opacity: 0;
  /* Slow, because a room should change the way a candle gutters and not the
     way a slide advances. Nobody should be able to point at the moment. */
  transition: opacity 2.4s ease-in-out;
}
.t-backdrop-layer.is-current { opacity: var(--t-backdrop-opacity, 0.5); }
.t-backdrop-layer img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Muted at the source rather than only buried under a scrim.
     Dimming with opacity alone fades the room toward the ink behind it, which
     flattens it and leaves the colour as strong as ever — a bright oil
     painting turned down is still a bright oil painting. Turning the
     photograph itself down keeps its contrast and its depth while taking it
     out of competition with the text. The values are the edition's: see
     theme.backdrops in app/zygote.json. */
  filter:
    brightness(var(--t-backdrop-brightness, 1))
    saturate(var(--t-backdrop-saturate, 1));
}

/* With a photograph behind it, the base layer stops being the table colour and
   becomes a scrim over the room: enough to keep parchment text at full
   contrast, little enough to still read as a lit interior. */
body.t-has-backdrop .t-ask::before,
body.t-has-backdrop .t-reveal::before {
  background:
    radial-gradient(60rem 40rem at 50% -8%, rgba(232, 182, 97, 0.12), transparent 60%),
    linear-gradient(180deg, rgba(13, 11, 9, 0.42) 0%, rgba(13, 11, 9, 0.66) 100%);
}
/* Two jobs in one layer: darken the corners so the room has depth, and put a
   soft pool of shadow under the middle where the question and the card are.
   Without the second half the text sits on whatever the photograph happens to
   be doing there, which across ten scenes is not something that can be relied
   on. */
body.t-has-backdrop .t-ask::after,
body.t-has-backdrop .t-reveal::after {
  background:
    radial-gradient(38rem 30rem at 50% 45%, rgba(13, 11, 9, 0.72) 0%, rgba(13, 11, 9, 0.35) 55%, transparent 78%),
    radial-gradient(120% 90% at 50% 40%, transparent 30%, rgba(0, 0, 0, 0.65) 100%);
}

@media (prefers-reduced-motion: reduce) {
  /* The swap still happens — it is a change of room, not an animation — but it
     happens at once rather than dissolving. */
  .t-backdrop-layer { transition: none; }
}

/* ---- the disclaimer ----

   Small and quiet, but never hidden: it sits under the answer on the reveal,
   under the question box on the ask screen, and in the footer of every page
   that is not the reading flow. Muted rather than shouted — a warning styled
   like a warning is read once and then filtered out. */

.t-disclaimer {
  max-width: var(--t-measure);
  margin: 1.75rem auto 0;
  color: var(--t-muted);
  font-family: var(--t-ui);
  font-size: 0.78rem;
  line-height: 1.6;
}
.t-disclaimer a { color: var(--t-brass); }
.t-disclaimer-quiet { margin-top: 0.6rem; opacity: 0.85; }

.t-footer .t-disclaimer { margin: 0.35rem 0 0; }

/* ---- the cookie dialog ----

   Drawn only where there is a measurement id to consent to, so on most
   deployments none of this is ever used — see google_analytics.htm.

   A bar along the bottom rather than a modal over the middle: nothing here is
   urgent enough to interrupt a reading, and a dialog that covers the card
   people came for gets dismissed unread, whichever button is nearest. The
   three buttons are the same size and the same weight on purpose. */

.t-consent {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  padding: 1rem 1.25rem;
  color: var(--t-parchment);
  background: rgba(13, 11, 9, 0.97);
  border-top: 1px solid rgba(168, 130, 60, 0.45);
  box-shadow: 0 -0.6rem 2rem rgba(0, 0, 0, 0.45);
  font-family: var(--t-ui);
  font-size: 0.85rem;
  line-height: 1.55;
}
.t-consent[hidden] { display: none; }

.t-consent-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  max-width: 72rem;
  margin: 0 auto;
}
.t-consent-words { max-width: 46rem; }
.t-consent-title {
  display: block;
  margin-bottom: 0.2rem;
  font-family: var(--t-display);
  font-size: 1.05rem;
  font-weight: 400;
  color: var(--t-candle);
}
.t-consent-text { margin: 0; color: var(--t-parchment); }
.t-consent-text a { color: var(--t-candle); }

.t-consent-buttons { display: flex; flex-wrap: wrap; gap: 0.6rem; }

.t-consent-btn {
  flex: 0 0 auto;
  padding: 0.55rem 1rem;
  font-family: var(--t-ui);
  font-size: 0.85rem;
  color: var(--t-table);
  background: var(--t-candle);
  border: 1px solid var(--t-candle);
  border-radius: 2px;
  cursor: pointer;
}
/* Equal weight, not equal colour: "no" must be as easy to press as "yes", and
   the ICO has said as much. Same size, same type, same row. */
.t-consent-btn-quiet {
  color: var(--t-parchment);
  background: transparent;
  border-color: rgba(168, 130, 60, 0.55);
}
.t-consent-btn:hover { border-color: var(--t-candleglow); }

.t-consent-details {
  max-width: 72rem;
  margin: 1rem auto 0;
  padding-top: 1rem;
  border-top: 1px solid rgba(168, 130, 60, 0.25);
}
.t-consent-details[hidden] { display: none; }
.t-consent-group { margin-bottom: 1rem; max-width: 46rem; }
.t-consent-switch {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  color: var(--t-candle);
  cursor: pointer;
}
.t-consent-switch input { accent-color: var(--t-brass); }
.t-consent-switch input[disabled] { cursor: default; }
.t-consent-group-text { margin: 0.3rem 0 0 1.7rem; color: var(--t-muted); }

@media (max-width: 46rem) {
  .t-consent { max-height: 80vh; overflow-y: auto; }
  .t-consent-inner { flex-direction: column; align-items: flex-start; gap: 0.9rem; }
  .t-consent-buttons { width: 100%; }
  .t-consent-btn { flex: 1 1 auto; text-align: center; }
}

/* ---- wiki ----

   The pages search brings people in on. Nothing here loads a bundle or a
   remote font, and the layout stays a single column: this is text, and the
   measure is the design. */

.t-wiki { max-width: 58rem; margin: 0 auto; }

.t-wiki-crumbs {
  margin: 0 0 1.75rem;
  color: var(--t-muted);
  font-family: var(--t-ui);
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
}
.t-wiki-crumbs a { color: var(--t-brass); text-decoration: none; }
.t-wiki-crumbs a:hover { color: var(--t-candle); }

.t-wiki-body h2 {
  font-family: var(--t-display);
  font-weight: 400;
  font-size: 1.45rem;
  color: var(--t-candle);
  margin: 2.5rem 0 0.75rem;
}
.t-wiki-body ul { padding-left: 1.1rem; }
.t-wiki-body li { margin-bottom: 0.5rem; }
.t-wiki-body em { color: var(--t-muted); font-style: italic; }

/* The card itself. Floated beside the meanings where there is room for both,
   and above them where there is not — a 420px card next to a 68ch measure on a
   phone would leave a column two words wide. */
.t-wiki-card {
  display: block;
  width: min(15rem, 55%);
  height: auto;
  margin: 0 0 1.5rem;
  border-radius: 3px;
  box-shadow: 0 0.9rem 2rem rgba(0, 0, 0, 0.45);
}

@media (min-width: 46rem) {
  .t-wiki-card {
    float: right;
    width: 16rem;
    margin: 0.35rem 0 1.5rem 2rem;
  }
}

/* Where the page ends: the thing the site actually does. */
.t-wiki-ask {
  clear: both;
  max-width: var(--t-measure);
  margin: 3rem 0 0;
  padding: 1.5rem;
  border: 1px solid rgba(168, 130, 60, 0.32);
  background: rgba(0, 0, 0, 0.2);
}
.t-wiki-ask-lead {
  margin: 0 0 1rem;
  font-family: var(--t-display);
  font-size: 1.15rem;
  line-height: 1.45;
  color: var(--t-parchment);
}

.t-wiki-missing { max-width: var(--t-measure); }
.t-wiki-missing h1 {
  font-family: var(--t-display);
  font-weight: 400;
  font-size: clamp(1.9rem, 5vw, 2.6rem);
  margin: 0 0 1rem;
}
.t-wiki-missing-links { display: flex; align-items: center; gap: 1.25rem; }
.t-wiki-missing-links a:not(.t-button) { color: var(--t-candle); }

/* ---- journal ---- */

.t-journal { max-width: 58rem; margin: 0 auto; }
.t-journal a { color: var(--t-candle); }
.t-journal-head { max-width: var(--t-measure); margin-bottom: 2.5rem; }
.t-eyebrow {
  margin: 0 0 0.35rem;
  color: var(--t-brass);
  font-family: var(--t-ui);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.t-journal-head h1 {
  margin: 0 0 0.75rem;
  font-family: var(--t-display);
  font-size: clamp(2rem, 6vw, 3rem);
  font-weight: 400;
  line-height: 1.1;
}
.t-journal-guest, .t-journal-empty {
  padding: 1rem 1.15rem;
  border: 1px solid rgba(168, 130, 60, 0.32);
  background: rgba(0, 0, 0, 0.18);
}
.t-journal-list { display: grid; gap: 1.4rem; }
.t-journal-entry {
  display: grid;
  grid-template-columns: 8rem minmax(0, 1fr);
  gap: 1.4rem;
  padding: 1.25rem;
  border: 1px solid rgba(168, 130, 60, 0.25);
  background: rgba(0, 0, 0, 0.2);
}
.t-journal-card img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 3px;
  box-shadow: 0 0.7rem 1.5rem rgba(0, 0, 0, 0.35);
}
.t-journal-card img.is-reversed { transform: rotate(180deg); }
.t-journal-copy time {
  color: var(--t-muted);
  font-family: var(--t-ui);
  font-size: 0.82rem;
}
.t-journal-copy h2 {
  margin: 0.25rem 0 0.35rem;
  font-family: var(--t-display);
  font-size: 1.45rem;
  font-weight: 400;
  line-height: 1.25;
}
.t-journal-copy h2 a { color: var(--t-parchment); text-decoration: none; }
.t-journal-card-name, .t-journal-verdict { color: var(--t-candle); }
.t-journal-deep {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid rgba(168, 130, 60, 0.2);
  color: #d4c9b4;
}
.t-journal-interpret {
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 1px solid rgba(168, 130, 60, 0.2);
  font-family: var(--t-ui);
  font-size: 0.9rem;
}
.t-journal-interpret a { text-decoration: none; border-bottom: 1px solid rgba(168, 130, 60, 0.5); }
.t-journal-interpret a:hover { border-bottom-color: var(--t-candle); }
.t-journal-pending { color: var(--t-muted); }
/* ---- what you have bought ---- */

.t-purchases { margin-top: 2.5rem; }
.t-purchases h2 {
  margin: 0 0 0.75rem;
  font-family: var(--t-display);
  font-size: 1.3rem;
  font-weight: 400;
}
.t-purchase-list { margin: 0; padding: 0; list-style: none; }
.t-purchase {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 0.9rem;
  padding: 0.7rem 0;
  border-top: 1px solid rgba(168, 130, 60, 0.2);
  font-family: var(--t-ui);
  font-size: 0.92rem;
}
.t-purchase time { color: var(--t-muted); min-width: 8.5rem; }
.t-purchase-what { flex: 1 1 8rem; }
.t-purchase-price { color: var(--t-candle); }
/* An attempt that never completed is history and not an achievement: it is
   here so somebody who thinks they paid can see what actually happened, and
   it should not read like a receipt. */
.t-purchase.is-unfinished { color: var(--t-muted); }
.t-purchase.is-unfinished .t-purchase-price { color: inherit; }
.t-purchase-state { flex-basis: 100%; color: var(--t-muted); font-size: 0.85rem; }
.t-purchase-test {
  display: inline-block;
  margin-left: 0.4rem;
  padding: 0.05rem 0.4rem;
  border: 1px solid rgba(168, 130, 60, 0.4);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.7rem;
}
@media (max-width: 30rem) {
  .t-purchase time { min-width: 0; flex-basis: 100%; }
}

.t-pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 1.25rem;
  margin-top: 2rem;
  font-family: var(--t-ui);
}
.t-button {
  display: inline-block;
  padding: 0.55rem 1rem;
  color: var(--t-table) !important;
  background: var(--t-candle);
  text-decoration: none;
}
@media (max-width: 38rem) {
  .t-journal-entry { grid-template-columns: 5.5rem minmax(0, 1fr); gap: 1rem; padding: 0.9rem; }
  .t-journal-deep, .t-journal-interpret { grid-column: 1 / -1; }
}

/* ---- footer ---- */

.t-footer {
  border-top: 1px solid rgba(168, 130, 60, 0.25);
  padding: 2rem 0 3rem;
  font-family: var(--t-ui);
  font-size: 0.875rem;
  color: var(--t-muted);
}
.t-footer a { color: var(--t-muted); text-decoration: none; }
.t-footer a:hover { color: var(--t-parchment); }
.t-footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  margin-bottom: 1.5rem;
}
.t-footer-legal > div { margin-bottom: 0.35rem; }
/* The artist's name. Public domain requires no attribution — this is here
 * because she went uncredited for most of a century. */
.t-deck-credit { font-style: italic; }

/* ---- the reading flow's shell ---- */
/* Only what has to exist before the bundle runs: the ground colour, so the
 * page is never a white flash, and the noscript fallback. Everything else is
 * the React app's, themed from the Zygote. */

body.t-reading {
  margin: 0;
  background: var(--t-table);
  color: var(--t-parchment);
  font-family: var(--t-body);
}
.t-noscript {
  max-width: var(--t-measure);
  margin: 4rem auto;
  padding: 0 1.25rem;
  text-align: center;
}
.t-noscript a { color: var(--t-candle); }

/* =========================================================================
   The ask screen.

   Server-rendered and styled here so the page is complete before any
   JavaScript runs. React hydrates this markup in Phase 3 and adds the shuffle
   and the reveal; it does not redraw it.

   The atmosphere is built from gradients rather than images on purpose — the
   theme's textures are not in the repository yet, and candlelight is a radial
   gradient before it is a photograph. When the artwork lands it layers on top
   of this rather than replacing it, so a missing file is never a blank page.
   ========================================================================= */

.t-visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.t-ask {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 2rem 1.25rem;
  position: relative;
  isolation: isolate;
}

/* Candlelight: a warm pool from above, falling off into the dark of the table.
   Two stops rather than one, because a single radial reads as a spotlight and
   this wants to read as a flame in a room. */
.t-ask::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(60rem 40rem at 50% -8%, rgba(232, 182, 97, 0.16), transparent 60%),
    radial-gradient(30rem 24rem at 50% 4%, rgba(255, 215, 154, 0.10), transparent 70%),
    var(--t-table);
}

/* The vignette, and the grain the theme asks for. Both fixed, so scrolling a
   long question does not drag the atmosphere with it. */
.t-ask::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(120% 90% at 50% 40%, transparent 45%, rgba(0, 0, 0, 0.55) 100%);
}

.t-ask-inner {
  width: 100%;
  max-width: 34rem;
  text-align: center;
  margin: auto 0;
  /* A flex item defaults to min-width:auto, which refuses to shrink below its
     content's intrinsic width — and a <textarea> brings one with it, from its
     `cols` attribute. On a narrow phone that pushed the whole column wider
     than the viewport and the page scrolled sideways. This is the standard
     fix and it has to stay. */
  min-width: 0;
}

.t-ask-title {
  font-family: var(--t-display);
  font-weight: 400;
  font-size: clamp(2.2rem, 8vw, 3.4rem);
  line-height: 1.05;
  letter-spacing: 0.01em;
  margin: 0 0 0.6rem;
  color: var(--t-parchment);
  /* The faintest glow, as if the page itself were near the candle. */
  text-shadow: 0 0 2.5rem rgba(232, 182, 97, 0.28);
}

.t-ask-sub {
  font-family: var(--t-body);
  font-size: 1.0625rem;
  color: var(--t-muted);
  margin: 0 0 2.25rem;
}

.t-ask-form { margin: 0; }

.t-ask-input {
  width: 100%;
  max-width: 100%;
  display: block;
  /* 16px minimum, or iOS Safari zooms the whole composition on focus. */
  font-size: 1.0625rem;
  font-family: var(--t-body);
  line-height: 1.5;
  color: var(--t-parchment);
  background: rgba(0, 0, 0, 0.28);
  border: 1px solid rgba(168, 130, 60, 0.35);
  border-radius: 3px;
  padding: 0.9rem 1rem;
  resize: none;
  text-align: center;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}
.t-ask-input::placeholder { color: rgba(138, 127, 109, 0.75); }
.t-ask-input:focus {
  outline: none;
  border-color: var(--t-candle);
  box-shadow: 0 0 0 1px rgba(232, 182, 97, 0.25), 0 0 2rem rgba(232, 182, 97, 0.12);
}

.t-ask-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 1.25rem;
}

.t-ask-submit {
  font-family: var(--t-ui);
  font-size: 0.9375rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--t-table);
  background: var(--t-candle);
  border: 0;
  border-radius: 3px;
  padding: 0.75rem 1.75rem;
  cursor: pointer;
  transition: background 160ms ease, transform 160ms ease;
}
.t-ask-submit:hover { background: #f2c87d; }
.t-ask-submit:active { transform: translateY(1px); }

.t-ask-voice {
  font-size: 1.125rem;
  line-height: 1;
  color: var(--t-candle);
  background: transparent;
  border: 1px solid rgba(168, 130, 60, 0.35);
  border-radius: 3px;
  padding: 0.7rem 0.85rem;
  cursor: pointer;
}
.t-ask-voice:hover { border-color: var(--t-candle); }
.t-ask-voice svg { display: block; width: 1.25rem; height: 1.25rem; fill: currentColor; stroke: currentColor; }
/* Whichever face is not in use is not in the layout either, so the button does
   not change size when it starts listening. */
.t-ask-voice .t-ask-voice-stop { display: none; }
.t-ask-voice.is-listening .t-ask-voice-mic { display: none; }
.t-ask-voice.is-listening .t-ask-voice-stop { display: block; }
.t-ask-voice[disabled] { cursor: default; opacity: 0.6; }

/* Listening. The candle pulse is the only thing on the screen that says the
   microphone is open, so it is deliberately obvious — and it stops for anyone
   who asked not to be moved, who gets the steady lit border instead. */
.t-ask-voice.is-listening {
  color: var(--t-parchment);
  border-color: var(--t-candle);
  box-shadow: 0 0 0 0 rgba(232, 182, 97, 0.5);
  animation: t-voice-pulse 1.6s ease-out infinite;
}
.t-ask-voice.is-working { opacity: 0.7; }

@keyframes t-voice-pulse {
  70% { box-shadow: 0 0 0 0.55rem rgba(232, 182, 97, 0); }
  100% { box-shadow: 0 0 0 0 rgba(232, 182, 97, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .t-ask-voice.is-listening { animation: none; box-shadow: 0 0 0.6rem rgba(232, 182, 97, 0.35); }
}

/* What the microphone heard, while it is hearing it. Empty until there is
   something to say, so the ask screen keeps its one-thing-on-it shape. */
.t-ask-voice-status {
  margin: 0.85rem 0 0;
  min-height: 1.2em;
  font-family: var(--t-ui);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--t-muted);
}
.t-ask-voice-status:empty { margin: 0; }

.t-ask-notice {
  margin: 1.5rem 0 0;
  font-family: var(--t-ui);
  font-size: 0.8125rem;
  color: var(--t-accent);
  background: rgba(107, 47, 47, 0.16);
  border: 1px solid rgba(107, 47, 47, 0.45);
  border-radius: 3px;
  padding: 0.6rem 0.9rem;
}

.t-ask-free {
  margin: 1.75rem 0 0;
  font-family: var(--t-ui);
  font-size: 0.8125rem;
  color: var(--t-muted);
}
/* The way to buy more sits on the allowance line rather than in a panel of its
   own — the ask screen holds the question and almost nothing else. It has to be
   given the site's colour explicitly: this is one of two screens with no
   `.longtext` or `.t-footer` around it, so an unstyled link here is browser
   blue, and then browser purple once it has been followed. */
.t-ask-free a { color: var(--t-candle); }
.t-ask-free a:visited { color: var(--t-candle); }
.t-ask-free a:hover { color: #f0c477; }

.t-ask-foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1.25rem;
  font-family: var(--t-ui);
  font-size: 0.8125rem;
  padding-top: 2rem;
}
.t-ask-foot a { color: rgba(138, 127, 109, 0.8); text-decoration: none; }
.t-ask-foot a:hover { color: var(--t-parchment); }

.t-deep {
  margin: 2rem 0 0;
  padding: 1.5rem 1.25rem;
  border: 1px solid rgba(168, 130, 60, 0.28);
  border-radius: 4px;
  background: rgba(18, 13, 10, 0.42);
}
.t-deep-button { max-width: 100%; }
.t-deep-text {
  white-space: pre-wrap;
  text-align: left;
  font-family: var(--t-body);
  line-height: 1.7;
  color: var(--t-parchment);
}
.t-deep-working, .t-deep-error {
  margin: 0.9rem 0 0;
  font-family: var(--t-ui);
  font-size: 0.8125rem;
  color: var(--t-muted);
}
.t-deep-error { color: var(--t-accent); }
.t-deep-retry {
  margin-top: 0.75rem;
  color: var(--t-candle);
  background: transparent;
  border: 0;
  text-decoration: underline;
  cursor: pointer;
}

/* A small scrying sphere while the model writes. Entirely CSS so the edition's
   candle/table palette carries it, and there is no extra image on the wait. */
.t-scrying {
  display: grid;
  justify-items: center;
  padding: 0.35rem 0 0;
  color: var(--t-muted);
  font-family: var(--t-ui);
  font-size: 0.8125rem;
}
.t-scrying-orb {
  position: relative;
  width: 6.75rem;
  aspect-ratio: 1;
  overflow: hidden;
  border: 1px solid rgba(232, 182, 97, 0.48);
  border-radius: 50%;
  background:
    radial-gradient(circle at 34% 27%, rgba(255, 239, 205, 0.48) 0 2%, transparent 10%),
    radial-gradient(circle at 48% 58%, rgba(111, 78, 132, 0.42), transparent 49%),
    radial-gradient(circle at 50% 50%, rgba(67, 46, 79, 0.72), rgba(10, 8, 13, 0.96) 72%);
  box-shadow:
    inset -1rem -1.2rem 2rem rgba(0, 0, 0, 0.55),
    inset 0.6rem 0.5rem 1.2rem rgba(255, 224, 172, 0.1),
    0 0 1.7rem rgba(232, 182, 97, 0.2),
    0 1.1rem 2.2rem rgba(0, 0, 0, 0.65);
  animation: t-orb-breathe 2.2s ease-in-out infinite;
}
.t-scrying-mist {
  position: absolute;
  width: 7rem;
  height: 2.6rem;
  border-radius: 50%;
  background: radial-gradient(ellipse, rgba(226, 207, 235, 0.3), transparent 68%);
  filter: blur(5px);
  animation: t-orb-drift 3s ease-in-out infinite alternate;
}
.t-scrying-mist-one { top: 22%; left: -28%; transform: rotate(18deg); }
.t-scrying-mist-two {
  right: -32%;
  bottom: 18%;
  transform: rotate(-14deg);
  animation-delay: -2.2s;
  animation-direction: alternate-reverse;
}
.t-scrying-star {
  position: absolute;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: #ffe6ad;
  box-shadow: 0 0 0.55rem #f3bd69;
  animation: t-orb-star 1.35s ease-in-out infinite;
}
.t-scrying-star-one { top: 37%; left: 31%; }
.t-scrying-star-two { right: 27%; bottom: 31%; animation-delay: -1.1s; }
.t-scrying-stand {
  width: 5.25rem;
  height: 1.15rem;
  margin-top: -0.25rem;
  border-radius: 50% 50% 35% 35%;
  border: 1px solid rgba(168, 130, 60, 0.48);
  background: linear-gradient(#5f4727, #21170e 68%);
  box-shadow: 0 0.7rem 1.2rem rgba(0, 0, 0, 0.55);
}
.t-scrying p { margin: 1.15rem 0 0; letter-spacing: 0.035em; }
.t-scrying-status { min-height: 1.2em; }
.t-scrying-progress {
  position: relative;
  width: min(15rem, 72vw);
  height: 2px;
  margin-top: 0.85rem;
  overflow: hidden;
  border-radius: 2px;
  background: rgba(168, 130, 60, 0.18);
}
.t-scrying-progress span {
  position: absolute;
  inset-block: 0;
  left: -42%;
  width: 42%;
  border-radius: inherit;
  background: linear-gradient(90deg, transparent, var(--t-candle) 45%, #ffe6ad 60%, transparent);
  box-shadow: 0 0 0.65rem rgba(232, 182, 97, 0.65);
  animation: t-reading-progress 1.15s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}

@keyframes t-orb-breathe {
  0%, 100% { box-shadow: inset -1rem -1.2rem 2rem rgba(0,0,0,.55), 0 0 1.4rem rgba(232,182,97,.15), 0 1.1rem 2.2rem rgba(0,0,0,.65); }
  50% { box-shadow: inset -1rem -1.2rem 2rem rgba(0,0,0,.48), 0 0 2.5rem rgba(232,182,97,.31), 0 1.1rem 2.2rem rgba(0,0,0,.65); }
}
@keyframes t-orb-drift {
  from { translate: -0.6rem 0.15rem; opacity: 0.4; }
  to { translate: 1.2rem -0.25rem; opacity: 0.9; }
}
@keyframes t-orb-star {
  0%, 100% { scale: 0.5; opacity: 0.25; }
  50% { scale: 1.4; opacity: 1; }
}
@keyframes t-reading-progress {
  from { translate: 0; }
  to { translate: 340%; }
}

@media (prefers-reduced-motion: reduce) {
  .t-scrying-orb, .t-scrying-mist, .t-scrying-star, .t-scrying-progress span { animation: none; }
  .t-scrying-progress span { left: 29%; }
}

/* Someone who has asked not to be moved gets no glow transitions either. */
@media (prefers-reduced-motion: reduce) {
  .t-ask-input, .t-ask-submit { transition: none; }
}

/* =========================================================================
   The reveal.

   Shares the ask screen's ground and candlelight (.t-ask::before is fixed and
   this reuses the same treatment), so moving from one to the other feels like
   staying in the same room.
   ========================================================================= */

.t-reveal {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 2.5rem 1.25rem 2rem;
  position: relative;
  isolation: isolate;
}
.t-reveal::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(60rem 40rem at 50% -8%, rgba(232, 182, 97, 0.16), transparent 60%),
    radial-gradient(30rem 24rem at 50% 4%, rgba(255, 215, 154, 0.10), transparent 70%),
    var(--t-table);
}
.t-reveal::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(120% 90% at 50% 40%, transparent 45%, rgba(0, 0, 0, 0.55) 100%);
}

.t-reveal-inner {
  width: 100%;
  max-width: 34rem;
  text-align: center;
  margin: auto 0;
  min-width: 0;
}

.t-reveal-question {
  font-family: var(--t-body);
  font-style: italic;
  font-size: 1.0625rem;
  color: var(--t-muted);
  margin: 0 0 1.75rem;
}

/* The card. A warm rim rather than a hard border — it should look lit, not
   framed. The aspect-ratio matches what deck-import renders, so the space is
   reserved before the image arrives and nothing shifts. */
.t-card {
  margin: 0 auto 1.5rem;
  width: min(62vw, 20rem);
  aspect-ratio: 420 / 726;
  border-radius: 6px;
  overflow: hidden;
  box-shadow:
    0 0 0 1px rgba(168, 130, 60, 0.4),
    0 1.5rem 3rem rgba(0, 0, 0, 0.55),
    0 0 4rem rgba(232, 182, 97, 0.14);
}
.t-card img { display: block; width: 100%; height: 100%; }

/* A reversed card is shown reversed. Printing the reversed *meaning* beside an
   upright picture is the one thing a tarot reader would never do. */
.t-card-reversed img { transform: rotate(180deg); }

.t-card-name {
  font-family: var(--t-display);
  font-weight: 400;
  font-size: clamp(1.8rem, 6vw, 2.5rem);
  line-height: 1.1;
  margin: 0 0 0.25rem;
  color: var(--t-parchment);
  text-shadow: 0 0 2.5rem rgba(232, 182, 97, 0.25);
}
.t-card-orientation {
  font-family: var(--t-ui);
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--t-brass);
  margin: 0 0 0.75rem;
}

.t-verdict {
  font-family: var(--t-display);
  font-size: clamp(1.6rem, 5vw, 2.1rem);
  letter-spacing: 0.04em;
  margin: 1rem 0 1.25rem;
}
.t-verdict-yes { color: var(--t-candle); }
.t-verdict-no { color: #c2706b; }
.t-verdict-maybe { color: var(--t-muted); }

.t-card-meaning {
  font-family: var(--t-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--t-parchment);
  margin: 0 auto 1.5rem;
  max-width: 30rem;
  text-align: left;
}

.t-card-keywords {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin: 0 0 2rem;
}
.t-card-keywords span {
  font-family: var(--t-ui);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  color: var(--t-brass);
  border: 1px solid rgba(168, 130, 60, 0.3);
  border-radius: 999px;
  padding: 0.25rem 0.7rem;
}

.t-explore { margin: 0 0 2rem; }
.t-explore a {
  font-family: var(--t-ui);
  font-size: 0.9375rem;
  letter-spacing: 0.04em;
  color: var(--t-candle);
  border-bottom: 1px solid rgba(232, 182, 97, 0.4);
  text-decoration: none;
  padding-bottom: 2px;
}

.t-not-saved {
  font-family: var(--t-ui);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--t-muted);
  background: rgba(0, 0, 0, 0.25);
  border: 1px solid rgba(168, 130, 60, 0.22);
  border-radius: 3px;
  padding: 0.7rem 0.9rem;
  margin: 0 0 1.75rem;
}
.t-not-saved a { color: var(--t-candle); }

.t-reveal-again { margin: 0 0 1rem; }
.t-reveal-again a { display: inline-block; text-decoration: none; }

@media (prefers-reduced-motion: reduce) {
  .t-card { box-shadow: 0 0 0 1px rgba(168, 130, 60, 0.4), 0 1rem 2rem rgba(0,0,0,0.5); }
}

/* The reversed badge.
 *
 * On the card rather than beside the title, because the thing it explains is
 * the picture. Rotating a reversed card is correct — that is what reversed
 * means — but to anyone who does not already know the convention it reads as a
 * broken image, and a caption elsewhere on the page arrives too late to change
 * that first impression. */
.t-card { position: relative; }

.t-card-flag {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  font-family: var(--t-ui);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--t-table);
  background: var(--t-candle);
  padding: 0.4rem 0.5rem;
  text-align: center;
  line-height: 1.25;
}
.t-card-flag-mark { font-size: 0.9rem; line-height: 1; }

/* The badge is not rotated with the picture — it is the one thing on the card
   that has to stay the right way up. */
.t-card-reversed .t-card-flag { transform: none; }

.t-card-rev-suffix {
  font-size: 0.5em;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--t-brass);
  vertical-align: middle;
  white-space: nowrap;
}

/* =========================================================================
   Forms, the flash message and the account pages.

   These screens came over from cairnquest.co.uk as Bootstrap 5 markup driven
   by jQuery, and this site loads neither — see _outer/sections/assets_head.htm,
   where the whole point is that a page of text costs no framework. So the
   markup was rewritten against this block instead, and nothing below depends
   on a class it does not define itself.

   The rule that follows from that: **a form here must work with scripts off.**
   Every one of them is a plain POST the server answers with a redirect and a
   flash message. Script adds the strength meter, the anti-spam answer and the
   inline field errors — it is never what makes a form submit.
   ========================================================================= */

/* ---- the flash message ---- */
/* Set by beforePresenting() and read once. `is-error` is the only variant:
   a message is either something that went wrong or something that went right,
   and four severities of parchment box is three more than this site needs. */

.t-message {
  max-width: var(--t-measure);
  margin: 0 0 2rem;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--t-brass);
  border-left-width: 3px;
  background: rgba(168, 130, 60, 0.12);
  font-family: var(--t-ui);
  font-size: 0.9375rem;
}
.t-message.is-error {
  border-color: #b4584f;
  background: rgba(180, 88, 79, 0.14);
}
.t-message a { color: var(--t-candle); }

/* The same message on the reading shell, which has no content column to put
   it at the top of. Fixed to the top of the window: the ask screen and the
   reveal are full-height and vertically centred, so a message stacked above
   them sits off the fold — and a thank-you nobody scrolls to is the same as
   no thank-you at all. Opaque, because it is read over a photograph. */
.t-flash {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 20;
  display: flex;
  justify-content: center;
  padding: 1rem 1.25rem;
  /* The room and the ask screen keep working under it — only the message
     itself takes the pointer. */
  pointer-events: none;
}
.t-flash .t-message {
  margin: 0;
  max-width: 32rem;
  pointer-events: auto;
  background:
    linear-gradient(rgba(168, 130, 60, 0.12), rgba(168, 130, 60, 0.12)),
    var(--t-table);
  box-shadow: 0 0.6rem 1.6rem rgba(0, 0, 0, 0.45);
}
.t-flash .t-message.is-error {
  background:
    linear-gradient(rgba(180, 88, 79, 0.14), rgba(180, 88, 79, 0.14)),
    var(--t-table);
}

/* ---- the auth pages: sign in, register, reset, activate ---- */

.t-auth {
  max-width: 27rem;
  margin: 1rem auto 0;
}
.t-auth-hero { text-align: center; margin-bottom: 1.75rem; }
.t-auth-hero h1 {
  font-family: var(--t-display);
  font-weight: 400;
  font-size: clamp(1.7rem, 4.5vw, 2.15rem);
  line-height: 1.15;
  margin: 0 0 0.5rem;
}
.t-auth-hero p {
  margin: 0;
  color: var(--t-muted);
  font-family: var(--t-ui);
  font-size: 0.9375rem;
}

/* The panel. A hairline of brass on a slightly lifted ground — the same
   language as .t-journal-entry, so the account pages and the journal read as
   one site rather than two. */
.t-panel {
  border: 1px solid rgba(168, 130, 60, 0.3);
  background: rgba(0, 0, 0, 0.22);
  padding: 1.75rem;
}
.t-panel + .t-panel { margin-top: 1.5rem; }
.t-panel-title {
  font-family: var(--t-display);
  font-weight: 400;
  font-size: 1.15rem;
  color: var(--t-candle);
  margin: 0 0 1rem;
}
.t-panel-danger { border-color: rgba(180, 88, 79, 0.55); }
.t-panel-danger .t-panel-title { color: #d98a80; }

/* ---- fields ---- */
/* Label above input, not Bootstrap's floating label. A floating label is a
   placeholder until it is focused, and this site's inputs sit on a dark ground
   where placeholder-grey is already close to unreadable. */

.t-field { margin-bottom: 1.1rem; }
.t-field label,
.t-label {
  display: block;
  margin-bottom: 0.35rem;
  font-family: var(--t-ui);
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--t-brass);
}
.t-input {
  display: block;
  width: 100%;
  padding: 0.7rem 0.85rem;
  color: var(--t-parchment);
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(168, 130, 60, 0.35);
  border-radius: 2px;
  font-family: var(--t-body);
  font-size: 1rem;
  line-height: 1.4;
}
.t-input::placeholder { color: #6f6555; }
.t-input:focus {
  outline: none;
  border-color: var(--t-candle);
  box-shadow: 0 0 0 3px rgba(232, 182, 97, 0.18);
}
.t-input:disabled { opacity: 0.6; }
/* The browser's own autofill paints its own background, which on a dark input
   is a white slab with white text in it. An inset shadow the size of the field
   is the only way to override it that Chrome and Safari both honour. */
.t-input:-webkit-autofill,
.t-input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--t-parchment);
  -webkit-box-shadow: 0 0 0 100px #241d16 inset;
  caret-color: var(--t-parchment);
}
.t-input[type="file"] { padding: 0.55rem 0.6rem; font-size: 0.9375rem; }

/* Field-level errors. Hidden until the field is marked, so the page does not
   open with a column of red text under empty inputs. */
.t-field-error {
  display: none;
  margin-top: 0.4rem;
  font-family: var(--t-ui);
  font-size: 0.8125rem;
  color: #e39a91;
}
.t-input.is-invalid { border-color: #b4584f; }
.t-input.is-invalid ~ .t-field-error { display: block; }

.t-field-note,
.t-note {
  margin: 0.45rem 0 0;
  font-family: var(--t-ui);
  font-size: 0.8125rem;
  color: var(--t-muted);
}
.t-note a { color: var(--t-candle); }

.t-field-row { display: flex; gap: 1rem; }
.t-field-row > * { flex: 1 1 0; min-width: 0; }
@media (max-width: 30rem) {
  .t-field-row { display: block; }
}

/* ---- checkboxes ---- */

.t-check {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  font-family: var(--t-ui);
  font-size: 0.875rem;
  color: #d4c9b4;
}
.t-check input[type="checkbox"] {
  flex: 0 0 auto;
  width: 1.05rem;
  height: 1.05rem;
  margin: 0.15rem 0 0;
  accent-color: var(--t-candle);
}
/* A checkbox's label is a sentence, not a field name — so it undoes the
   uppercase brass caption that .t-field label sets for the inputs above it. */
.t-check label {
  margin: 0;
  font-size: inherit;
  letter-spacing: normal;
  text-transform: none;
  color: inherit;
}
.t-check a { color: var(--t-candle); }
.t-check .t-field-error { margin-top: 0.2rem; }
.t-check input.is-invalid ~ label { color: #e39a91; }

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

.t-submit {
  display: block;
  width: 100%;
  padding: 0.8rem 1rem;
  color: var(--t-table);
  background: var(--t-candle);
  border: 1px solid var(--t-candle);
  border-radius: 2px;
  font-family: var(--t-ui);
  font-size: 1rem;
  letter-spacing: 0.02em;
  cursor: pointer;
}
.t-submit:hover { background: #f0c477; border-color: #f0c477; }
.t-submit[disabled] { opacity: 0.55; cursor: default; }

.t-submit-quiet {
  color: var(--t-parchment);
  background: transparent;
  border-color: rgba(168, 130, 60, 0.5);
}
.t-submit-quiet:hover { background: rgba(168, 130, 60, 0.15); border-color: var(--t-candle); }

.t-submit-danger {
  color: #e39a91;
  background: transparent;
  border-color: rgba(180, 88, 79, 0.6);
}
.t-submit-danger:hover { color: #fff; background: #8c3b34; border-color: #8c3b34; }

.t-submit-inline { display: inline-block; width: auto; }

/* A button that is really a link: "remove my picture", "revoke". */
.t-linkbutton {
  padding: 0;
  color: var(--t-muted);
  background: none;
  border: 0;
  font-family: var(--t-ui);
  font-size: 0.875rem;
  text-decoration: underline;
  cursor: pointer;
}
.t-linkbutton:hover { color: var(--t-parchment); }

/* ---- the row between the form and the social buttons ---- */

.t-auth-or {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin: 1.5rem 0;
  font-family: var(--t-ui);
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--t-muted);
}
.t-auth-or::before,
.t-auth-or::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: rgba(168, 130, 60, 0.3);
}

.t-social { display: grid; gap: 0.6rem; }
.t-social-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.7rem 1rem;
  border: 1px solid rgba(168, 130, 60, 0.4);
  border-radius: 2px;
  color: var(--t-parchment);
  background: rgba(0, 0, 0, 0.25);
  font-family: var(--t-ui);
  font-size: 0.9375rem;
  text-decoration: none;
}
.t-social-btn:hover { border-color: var(--t-candle); background: rgba(232, 182, 97, 0.1); }
.t-social-btn svg { width: 1.15rem; height: 1.15rem; flex: 0 0 auto; }

.t-auth-foot {
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid rgba(168, 130, 60, 0.2);
  text-align: center;
  font-family: var(--t-ui);
  font-size: 0.9375rem;
  color: var(--t-muted);
}
.t-auth-foot a { color: var(--t-candle); }

/* The forgot-password link, level with the "remember me" box. */
.t-auth-aside {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}
.t-auth-aside a {
  font-family: var(--t-ui);
  font-size: 0.875rem;
  color: var(--t-candle);
}

/* ---- the password strength meter ---- */
/* Its "too weak" band is exactly what App\Handlers\User\Login::isPasswordTooWeak
   refuses, so the meter never says fair about a password the server will send
   back. Hidden until something is typed. */

.t-pw {
  margin: -0.4rem 0 1.1rem;
  font-family: var(--t-ui);
  font-size: 0.8125rem;
}
.t-pw[hidden] { display: none; }
.t-pw-track { display: flex; gap: 0.3rem; margin-bottom: 0.3rem; }
.t-pw-track span {
  flex: 1 1 0;
  height: 3px;
  background: rgba(168, 130, 60, 0.22);
}
.t-pw-label { color: var(--t-muted); }

.t-pw[data-score="0"] .t-pw-track span:nth-child(1) { background: #b4584f; }
.t-pw[data-score="0"] .t-pw-label { color: #e39a91; }
.t-pw[data-score="1"] .t-pw-track span:nth-child(-n+1) { background: #c98a3c; }
.t-pw[data-score="2"] .t-pw-track span:nth-child(-n+2) { background: var(--t-candle); }
.t-pw[data-score="3"] .t-pw-track span { background: #7fa86a; }
.t-pw[data-score="2"] .t-pw-label,
.t-pw[data-score="3"] .t-pw-label { color: var(--t-parchment); }

/* ---- the account pages ---- */

.t-account { max-width: 48rem; }
.t-account h1 {
  font-family: var(--t-display);
  font-weight: 400;
  font-size: clamp(1.8rem, 5vw, 2.4rem);
  margin: 0 0 1.75rem;
}
.t-account-hero {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  flex-wrap: wrap;
  margin-bottom: 1.5rem;
}
.t-account-who { min-width: 0; }
.t-account-name {
  font-family: var(--t-display);
  font-size: 1.4rem;
  margin: 0;
  word-break: break-word;
}
.t-account-email {
  font-family: var(--t-ui);
  font-size: 0.9375rem;
  color: var(--t-muted);
  word-break: break-word;
}
.t-badges { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem; }
.t-badge {
  padding: 0.15rem 0.55rem;
  border: 1px solid rgba(168, 130, 60, 0.45);
  font-family: var(--t-ui);
  font-size: 0.75rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--t-brass);
}

.t-rows { margin: 0; }
.t-row {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.7rem 0;
  border-bottom: 1px solid rgba(168, 130, 60, 0.18);
  font-family: var(--t-ui);
  font-size: 0.9375rem;
}
.t-row:last-child { border-bottom: 0; }
.t-row-label {
  flex: 0 0 7rem;
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--t-muted);
}
.t-row-value { flex: 1 1 12rem; min-width: 0; word-break: break-word; }

/* A change form is a <details>, not a modal. A modal needs a framework to open
   it; a disclosure opens itself, and one that fails to open still shows the
   form underneath instead of nothing at all. */
.t-disclose { margin-top: 0.9rem; }
.t-disclose > summary {
  display: inline-block;
  cursor: pointer;
  font-family: var(--t-ui);
  font-size: 0.875rem;
  color: var(--t-candle);
  list-style: none;
}
.t-disclose > summary::-webkit-details-marker { display: none; }
.t-disclose > summary::before { content: "+ "; }
.t-disclose[open] > summary::before { content: "\2212 "; }
.t-disclose-body {
  margin-top: 0.9rem;
  padding: 1.1rem;
  border: 1px solid rgba(168, 130, 60, 0.25);
  background: rgba(0, 0, 0, 0.2);
}

/* ---- the API token table ---- */

.t-table-scroll { overflow-x: auto; }
.t-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--t-ui);
  font-size: 0.875rem;
}
.t-table th,
.t-table td {
  padding: 0.6rem 0.75rem 0.6rem 0;
  text-align: left;
  border-bottom: 1px solid rgba(168, 130, 60, 0.18);
  white-space: nowrap;
}
.t-table th {
  font-weight: 400;
  font-size: 0.75rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--t-muted);
}
.t-table code {
  font-size: 0.8125rem;
  color: var(--t-candle);
}
.t-panel-center { text-align: center; }

/* ---- contact ---- */

.t-contact {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  gap: 2.5rem;
  align-items: start;
  max-width: 58rem;
}
.t-contact-aside {
  font-family: var(--t-ui);
  font-size: 0.9375rem;
  color: var(--t-muted);
}
.t-contact-aside strong { color: var(--t-parchment); }
@media (max-width: 44rem) {
  .t-contact { grid-template-columns: minmax(0, 1fr); gap: 1.75rem; }
}

/* The message box. Same input, only taller and free to be resized upwards. */
textarea.t-input { resize: vertical; min-height: 9rem; line-height: 1.6; }

/* The wall on the deep reading — an offer, not an error.
   Drawn in the reveal by DeepReading.jsx when this visitor has no free reading
   left and nothing in the balance. It sits where the "Explore this reading"
   button was, so the eye does not have to go looking for what changed. */
.t-deep-wall {
  max-width: 30rem;
  margin: 0 auto;
  text-align: center;
}
.t-deep-wall p {
  margin: 0 0 1.1rem;
  font-family: var(--t-ui);
  font-size: 0.9375rem;
  color: #d4c9b4;
}
.t-deep-wall .t-deep-button { text-decoration: none; display: inline-block; }

/* ---- the packs ---- */

.t-packs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 1rem;
  margin: 1.75rem 0;
}
.t-pack {
  border: 1px solid rgba(168, 130, 60, 0.3);
  background: rgba(0, 0, 0, 0.22);
  padding: 1.5rem 1.25rem;
  text-align: center;
}
.t-pack-count {
  font-family: var(--t-ui);
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--t-brass);
  margin: 0 0 0.5rem;
}
.t-pack-price {
  font-family: var(--t-display);
  font-size: 2rem;
  line-height: 1;
  margin: 0 0 0.35rem;
}
.t-pack-each {
  font-family: var(--t-ui);
  font-size: 0.8125rem;
  color: var(--t-muted);
  margin: 0 0 1.25rem;
}
.t-submit-link {
  display: block;
  text-align: center;
  text-decoration: none;
}
/* The "you can add more" aside on the allowance line. Quieter than the number
   it follows: it is reassurance, not an offer, and the ask screen is not a
   place to sell to somebody who has not yet had a reading. */
.t-ask-free-more { opacity: 0.75; }
