/* Sentence case since the 2026-10 redesign. These rules were written for the
   brush face, which needed capitals to hold a line. Fraunces does not, and a
   serif set in caps at heading size reads as a conference banner. */

/* ---- Ridgeline palette -----------------------------------------------------
   Kept together here because the three ranges only read as depth if they move
   as a set. Light: hazy blue receding to navy. Dark: the same recession, but
   the near range goes darker than the paper rather than lighter. */

:root {
  --ridge-1: #c2cedd;
  --ridge-2: #8ea4bd;
  --ridge-3: #4b6787;
  --path:    #f3ede2;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ridge-1: #22303f;
    --ridge-2: #1a2733;
    --ridge-3: #101a24;
    --path:    #d8cdb8;
  }
}

:root[data-theme="dark"] {
  --ridge-1: #22303f;
  --ridge-2: #1a2733;
  --ridge-3: #101a24;
  --path:    #d8cdb8;
}

/* ---- Boot / toast ---------------------------------------------------------- */

.boot {
  min-height: 100vh;
  display: grid; place-items: center;
  color: var(--ink-faint);
  font-size: .85rem;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.toast {
  position: fixed; left: 50%; bottom: 1.5rem;
  transform: translateX(-50%);
  max-width: min(30rem, calc(100vw - 2rem));
  padding: .7rem 1.15rem;
  background: var(--ink); color: var(--paper-raised);
  border-radius: 999px;
  font-size: .82rem;
  text-align: center;
  box-shadow: var(--shadow-lg);
  z-index: 50;
  animation: toast-in .18s ease-out;
}
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, 6px); } }

/* ---- Landing → gate transition ------------------------------------------------
   Used ONLY by the closing "Start day one" button, where the reader has just
   finished the case and is choosing to act. The ribbon control stays instant:
   a control that is always on screen should never make you wait.

   The gate fades as a whole but only `.gate__inner` moves. A transform on
   `.gate` itself would make it the containing block for the `position: fixed`
   ridgeline inside it, and the artwork would jump mid-animation. */


/* ---- Signed-out gate --------------------------------------------------------- */

.gate {
  position: relative;
  min-height: 100vh;
  display: grid; place-items: center;
  padding: 2.5rem 1.25rem 0;
  overflow: hidden;
}

.gate__inner {
  position: relative; z-index: 2;
  width: 100%; max-width: 27rem;
  display: grid; gap: 1.5rem;
  padding-bottom: 13rem;   /* keeps the card clear of the ridgeline */
}

.gate__brand { text-align: center; display: grid; gap: .7rem; justify-items: center; }
.gate__title { display: flex; flex-direction: column; align-items: center; }
.gate__sub {
  font-size: .72rem; font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase; color: var(--ink-soft); max-width: 22rem;
}
.gate__hand { margin-top: .2rem; }

.gate__card { padding: 1.6rem; }

/* Sits over the artwork, so it carries its own paper to stay readable. */
.gate__notice {
  font-size: .75rem; line-height: 1.6; color: var(--ink-faint);
  text-align: center; margin: 0;
  padding: .65rem .9rem;
  border-radius: 12px;
  background: color-mix(in srgb, var(--paper) 84%, transparent);
  backdrop-filter: blur(4px);
}
.gate__notice strong { color: var(--ink-soft); }

/* The cover's journey: ridgeline, winding path, flag at the summit.
   Fixed rather than absolute so it stays the horizon at the foot of the
   viewport. The gate grows taller than one screen on small displays, and an
   absolute ridgeline ends up below the fold where nobody sees it. */
.ridgeline {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 1;
  width: 100%;
  height: clamp(11rem, 30vh, 17rem);
  pointer-events: none;
}

/* On a short screen the artwork would crowd the sign-in form. Drop it there,
   but not on the landing hero, which gives it room of its own. */
@media (max-height: 620px) {
  .gate .ridgeline { display: none; }
  .gate__inner { padding-bottom: 2rem; }
}

/* Gate panels that replace the forms: email confirmation, 2FA challenge. */
.panel { text-align: center; }
.panel__title {
  font-family: var(--display);
  font-size: 1.8rem; line-height: 1.05;
  margin: .4rem 0 .6rem;
  letter-spacing: var(--display-tracking);
}
.panel__body {
  font-family: var(--serif);
  font-size: .97rem; line-height: 1.65; color: var(--ink-soft);
  margin-bottom: 1.25rem;
}
.panel__body strong { color: var(--ink); }
.panel .form { text-align: left; }

/* One-time codes are read off a screen and typed in a hurry. Big, spaced,
   tabular, so a transposed digit is obvious. */
.code-input {
  font-family: var(--mono);
  font-size: 1.5rem !important;
  letter-spacing: .5em;
  text-indent: .5em;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.tab {
  flex: 1; padding: .6rem .5rem; background: none; border: none;
  border-bottom: 3px solid transparent; margin-bottom: -1.5px;
  color: var(--ink-faint);
  font-size: .7rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  cursor: pointer;
}
.tab.is-active { color: var(--ink); border-bottom-color: var(--accent); }

/* ---- App chrome --------------------------------------------------------------- */

.app { min-height: 100vh; display: flex; flex-direction: column; }

.topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 1.25rem;
  padding: .65rem 1.35rem;
  background: color-mix(in srgb, var(--paper) 90%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1.5px solid var(--rule);
}
.topbar__brand .wordmark--sm em { color: var(--accent-ink); }

/* The theme control used to lead this group and carry the auto margin. It has
   moved to Account, so the nav carries it instead. */
.topbar__nav { margin-left: auto; display: flex; gap: .2rem; }
.topbar__nav a {
  padding: .45rem .75rem; border-radius: var(--radius);
  font-size: .7rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-faint);
  transition: color .15s, background .15s;
}
.topbar__nav a:hover { background: var(--paper-sunk); color: var(--ink); }
.topbar__nav a.is-active {
  color: var(--ink);
  background: var(--paper-sunk);
  box-shadow: inset 0 -3px 0 var(--accent);
}

.view { flex: 1; padding: 2.75rem 1.25rem 4rem; }
.view:focus { outline: none; }

.wrap { width: 100%; max-width: var(--measure); margin: 0 auto; }
.wrap--wide { max-width: 48rem; }

/* ---- Week context band --------------------------------------------------------- */

.context {
  position: relative;
  padding: 1.5rem 1.6rem 1.6rem;
  margin-bottom: 2.25rem;
  background: var(--paper-raised);
  border: 1.5px solid var(--rule);
  border-radius: 16px;
  box-shadow: var(--shadow);
  overflow: hidden;
}
/* Pillar color as a painted edge down the left. */
.context::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 6px;
  background: var(--pillar, var(--gold));
}

.prompt {
  padding: 1.05rem 1.25rem;
  border-left: 4px solid var(--accent);
  background: var(--paper-sunk);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-family: var(--serif);
  font-size: 1.04rem;
  line-height: 1.65;
  color: var(--ink-soft);
  margin-bottom: 1.75rem;
}

.page {
  padding: 1.9rem;
  background: var(--paper-raised);
  border: 1.5px solid var(--rule);
  border-radius: 16px;
  box-shadow: var(--shadow);
}

.empty {
  padding: 2.75rem 1.5rem;
  border: 1.5px dashed var(--rule-strong);
  border-radius: 16px;
  text-align: center;
  color: var(--ink-faint);
  font-family: var(--hand);
  font-size: 1.3rem;
}
.search { margin-left: auto; min-width: 12rem; flex: 1 1 12rem; max-width: 20rem; }
.search input {
  width: 100%; padding: .55rem .95rem;
  background: var(--paper-raised); border: 1.5px solid var(--rule-strong);
  border-radius: 999px; font-size: .85rem;
}
.search input:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* ---- Account -------------------------------------------------------------------------- */

.account-head { display: flex; align-items: center; gap: .9rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
.account-head h2 {
  font-family: var(--display);
  font-size: clamp(1.7rem, 5vw, 2.2rem);
  line-height: 1.05; font-weight: 600;
  letter-spacing: var(--display-tracking);
}

.section { margin-bottom: 2.25rem; padding-bottom: 2.25rem; border-bottom: 1.5px solid var(--rule); }
.section:last-child { border-bottom: none; }
.section h3 {
  font-size: .72rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink); margin-bottom: .4rem;
}
.section > p { font-size: .85rem; color: var(--ink-faint); margin-bottom: 1rem; max-width: 34rem; }
.section__actions { display: flex; gap: .6rem; flex-wrap: wrap; }

.kv { display: grid; grid-template-columns: auto 1fr; gap: .5rem 1.5rem; font-size: .88rem; }
.kv dt {
  font-size: .65rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-faint); align-self: center;
}

/* ---- Locked (no purchase) ------------------------------------------------------ */

.locked {
  padding: 2.25rem 2rem 2.5rem;
  background: var(--paper-raised);
  border: 1.5px solid var(--rule);
  border-radius: 16px;
  box-shadow: var(--shadow);
  text-align: center;
}
.locked .eyebrow--flanked { justify-content: center; margin-bottom: .8rem; }

@media (max-width: 560px) {
  .locked { padding: 1.5rem 1.15rem 1.75rem; }
}

/* ---- Two-factor -------------------------------------------------------------- */

.mfa-note {
  padding: .85rem 1rem;
  border: 1.5px dashed var(--rule-strong);
  border-radius: var(--radius);
  font-size: .85rem; line-height: 1.6; color: var(--ink-faint);
  max-width: 34rem;
}
.mfa-note code {
  font-family: var(--mono); font-size: .8em;
  padding: .1em .35em; border-radius: 4px; background: var(--paper-sunk);
}

.mfa-on { display: flex; align-items: center; gap: .75rem; }
.mfa-on__name { font-size: .9rem; color: var(--ink-soft); }

.mfa-enroll {
  max-width: 26rem;
  padding: 1.25rem;
  background: var(--paper-raised);
  border: 1.5px solid var(--rule);
  border-radius: 14px;
}
.mfa-steps {
  list-style: decimal; padding-left: 1.15rem; margin-bottom: 1.15rem;
  font-size: .88rem; line-height: 1.7; color: var(--ink-soft);
}
.mfa-steps li { margin-bottom: .2rem; }

/* White plate behind the QR: a dark-mode page would otherwise invert the
   contrast a scanner depends on. */
.mfa-qr {
  display: block; margin: 0 auto 1.1rem;
  padding: .6rem; background: #fff; border-radius: 10px;
  width: 180px; height: 180px;
}

.mfa-secret { margin-bottom: 1.1rem; display: grid; gap: .3rem; }
.mfa-secret code {
  font-family: var(--mono); font-size: .82rem; letter-spacing: .06em;
  word-break: break-all;
  padding: .55rem .7rem; border-radius: var(--radius);
  background: var(--paper-sunk); border: 1.5px solid var(--rule);
}
.pillar-stack .swipe { min-width: 11rem; justify-content: flex-start; }

/* ---- Small screens ---------------------------------------------------------------------- */

@media (max-width: 560px) {
  /* Brand + toggle + three nav items overflowed 375px, clipping the last item.
     Everything below is trimmed to fit rather than letting a control fall off
     the edge. min-width:0 lets the brand shrink instead of forcing the overflow
     onto the nav. */
  .topbar { gap: .4rem; padding: .55rem .7rem; }
  .topbar__brand { min-width: 0; overflow: hidden; }
  .topbar__brand .wordmark--sm { font-size: .95rem; white-space: nowrap; }
  .topbar__nav { gap: 0; flex: none; }
  .topbar__nav a { padding: .35rem .3rem; font-size: .58rem; letter-spacing: .04em; white-space: nowrap; }
  .view { padding: 1.9rem .9rem 3rem; }
  .tab { font-size: .62rem; letter-spacing: .07em; }
  .context { padding: 1.15rem 1.15rem 1.3rem; }
  .editor { padding: 1.15rem; min-height: 18rem; }
  .history-head h2 { font-size: 1.75rem; }
  .search { flex-basis: 100%; margin-left: 0; max-width: none; }
  .entry-row { grid-template-columns: 4.25rem 1fr; }
  .entry-row__words { display: none; }
  .gate__inner { padding-bottom: 11rem; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ---- Theme picker, on the Account page ---------------------------------------
   Three states rather than a two-way toggle, because "follow my device" is a
   real answer and the old toggle could not express it: once you had pressed it
   even once, the site stopped listening to the system setting for good, with
   nothing on screen saying so.

   Set out as a segmented control so the current choice is visible without
   being hovered, which is the whole reason this moved out of the ribbon. */

.themepick {
  display: inline-flex;
  padding: 3px;
  background: var(--paper-sunk);
  border: 1.5px solid var(--rule);
  border-radius: 999px;
}
.themepick__opt {
  padding: .5rem 1.05rem;
  font-family: inherit;
  font-size: .68rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft);
  background: none; border: none; border-radius: 999px;
  cursor: pointer;
  transition: background .2s ease, color .2s ease;
}
.themepick__opt:hover { color: var(--ink); }
.themepick__opt.is-on {
  color: var(--paper);
  background: var(--ink);
}
.themepick__opt:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (max-width: 520px) {
  .themepick { display: flex; width: 100%; }
  .themepick__opt { flex: 1; padding-inline: .4rem; }
}

/* ---- A few utilities ----------------------------------------------------------
   These replace inline `style` attributes. Inline styles are what oblige a
   Content-Security-Policy to allow `style-src 'unsafe-inline'`, which in turn
   lets any injected markup style the page. Six small classes are a cheap price
   for a policy that can refuse inline style outright. See deploy/README.md. */

.form--narrow { max-width: 22rem; }
.w-16  { max-width: 16rem; }
.mt-1  { margin-top: 1rem; }
.mt-sm { margin-top: .6rem; }
