/* ==========================================================================
   Calm the Moment - v2 UI prototype
   Shared stylesheet for every mockup page. Static HTML only, no framework,
   so it can be opened straight from disk in a browser.
   Palette and typography carried over from the published main site.
   ========================================================================== */

:root{
  --bg:#0F1E1C;
  --bg-soft:#162A27;
  --card:#1C332F;
  --card-2:#203934;
  --ink:#EAF2EF;
  --muted:#9DB5AE;
  --line:#2A443F;
  --glow:#8FD6C4;
  --glow-deep:#5FB8A3;
  --on-glow:#0C1917;
  --danger:#E88C7D;
  --warn:#E3C88A;
  --ok:#8FD6C4;
  --r-sm:10px; --r:12px; --r-lg:16px; --r-xl:20px;
}

*{margin:0;padding:0;box-sizing:border-box;}
html{scroll-behavior:smooth;}
body{
  background:var(--bg);color:var(--ink);
  font-family:'Karla',system-ui,-apple-system,sans-serif;
  font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4{font-family:'Newsreader',Georgia,serif;font-weight:500;letter-spacing:-.015em;line-height:1.18;}
a{color:var(--glow);text-decoration:none;}
a:hover{color:#A8E2D2;}
em{font-style:italic;color:var(--glow);}
code,.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.86em;}

/* ---------- prototype banner ---------- */
.proto{
  background:#2A2418;border-bottom:1px solid #4A3F22;color:var(--warn);
  font-size:.78rem;padding:7px 16px;text-align:center;letter-spacing:.04em;
}
.proto b{color:#F0DCA8;}
.proto a{color:var(--warn);text-decoration:underline;}

/* ---------- brand ---------- */
.brand{display:inline-flex;align-items:center;gap:11px;font-family:'Newsreader',serif;font-size:1.15rem;color:var(--ink);}
.dot{
  width:18px;height:18px;border-radius:50%;flex:none;
  background:radial-gradient(circle at 38% 35%,var(--glow) 0%,var(--glow-deep) 55%,#3E8A77 100%);
}
.dot-lg{width:56px;height:56px;box-shadow:0 0 28px rgba(143,214,196,.4);}
@media (prefers-reduced-motion:no-preference){
  .dot-breathe{animation:breathe 10s ease-in-out infinite;}
  @keyframes breathe{0%{transform:scale(.85);}40%{transform:scale(1.06);}100%{transform:scale(.85);}}
}

/* ---------- layout ---------- */
.wrap{max-width:1060px;margin:0 auto;padding:0 22px;}
.wrap-narrow{max-width:460px;margin:0 auto;padding:0 22px;}
.topbar{background:var(--card);border-bottom:1px solid var(--line);}
.topbar-in{display:flex;align-items:center;gap:26px;padding-block:15px;}
.topbar nav{display:flex;gap:22px;margin-left:auto;align-items:center;font-size:.94rem;}
.topbar nav a{color:var(--muted);}
.topbar nav a:hover,.topbar nav a.on{color:var(--ink);}
.avatar{
  width:32px;height:32px;border-radius:50%;background:var(--bg-soft);
  border:1px solid var(--line);display:grid;place-items:center;
  font-size:.8rem;color:var(--muted);
}
.page{padding:32px 0 80px;}

/* ---------- back link ----------
   Was a <p class="note"> wrapping a padded anchor, which stacked page padding,
   paragraph margin and anchor padding into an uneven gap. One element, one set
   of spacing, and still a 40px tap target. */
.back{
  display:inline-flex;
  align-items:center;
  gap:7px;
  font-size:.9rem;
  color:var(--muted);
  padding:10px 0;
  margin-bottom:4px;
}
.back:hover{color:var(--ink);}

/* Pages that are a single centred card sit lower, so the card is not jammed
   under the header. Was an inline padding-top repeated across five views. */
.page-centred{padding-top:64px;}
@media (max-width:620px){
  .page-centred{padding-top:36px;}
}
.page-head{margin-bottom:28px;}
.page-head h1{font-size:1.9rem;margin-bottom:6px;}
.page-head p{color:var(--muted);}
.kicker{font-size:.8rem;letter-spacing:.16em;text-transform:uppercase;color:var(--glow);margin-bottom:9px;}

/* ---------- cards ---------- */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);padding:24px;}
.panel{background:linear-gradient(160deg,var(--card) 0%,var(--bg-soft) 100%);
       border:1px solid var(--line);border-radius:var(--r-xl);padding:36px;}
.grid{display:grid;gap:16px;}
/* Grid items default to min-width:auto, so a wide child such as a table refuses
   to shrink and pushes the whole page past the viewport. This lets the child
   scroll inside its own .table-wrap instead. */
.grid > *{min-width:0;}
.grid-2{grid-template-columns:repeat(2,1fr);}
.grid-3{grid-template-columns:repeat(3,1fr);}
.grid-side{grid-template-columns:1.6fr 1fr;align-items:start;}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:12px 22px;font:700 .95rem 'Karla',sans-serif;
  background:var(--glow);color:var(--on-glow);border:none;border-radius:var(--r);
  cursor:pointer;transition:background .15s ease;
}
.btn:hover{background:#A8E2D2;color:var(--on-glow);}
.btn:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
.btn[disabled]{opacity:.45;cursor:not-allowed;}
.btn-ghost{background:transparent;color:var(--glow);border:1px solid var(--line);}
.btn-ghost:hover{background:var(--card-2);color:var(--glow);}
.btn-danger{background:transparent;border:1px solid var(--danger);color:var(--danger);}
.btn-danger:hover{background:rgba(232,140,125,.12);color:var(--danger);}
.btn-sm{padding:8px 15px;font-size:.86rem;}
.btn-block{width:100%;}

/* ---------- forms ---------- */
.field{margin-bottom:18px;}
.field label{display:block;font-size:.88rem;color:var(--muted);margin-bottom:7px;}
.field .hint{font-size:.8rem;color:var(--muted);margin-top:6px;}
.input,input[type=text],input[type=email],input[type=url],input[type=number],textarea,select{
  width:100%;padding:12px 14px;font:400 .98rem 'Karla',sans-serif;
  background:var(--bg-soft);color:var(--ink);
  border:1.5px solid var(--line);border-radius:var(--r);
}
textarea{min-height:110px;resize:vertical;}
.input:focus,input:focus,textarea:focus,select:focus{
  outline:2px solid var(--glow);outline-offset:1px;border-color:var(--glow);
}
::placeholder{color:#6E8A82;}
.checkline{display:flex;gap:10px;align-items:flex-start;font-size:.9rem;color:var(--muted);}
/* Browser default checkboxes are ~13px, too small to tap reliably. This one
   gates account deletion, so it gets a real target. The label is associated by
   "for", which makes the text tappable too. */
.checkline input[type=checkbox]{
  width:24px;height:24px;margin-top:1px;flex:none;
  accent-color:var(--glow);cursor:pointer;
}
.checkline label{cursor:pointer;padding:4px 0;}
.checkline input{width:auto;margin-top:4px;}

/* ---------- OTP input ---------- */
.otp{display:flex;gap:10px;justify-content:center;margin:6px 0 4px;}
.otp input{
  width:52px;height:60px;text-align:center;
  font:600 1.5rem ui-monospace,Menlo,monospace;
  background:var(--bg-soft);color:var(--ink);
  border:1.5px solid var(--line);border-radius:var(--r);
}
.otp input:focus{outline:2px solid var(--glow);outline-offset:1px;border-color:var(--glow);}
.otp-meta{display:flex;justify-content:space-between;align-items:center;
          font-size:.84rem;color:var(--muted);margin-top:16px;}

/* ---------- tables ---------- */
.table-wrap{overflow-x:auto;border:1px solid var(--line);border-radius:var(--r-lg);background:var(--card);}
table{width:100%;border-collapse:collapse;font-size:.92rem;min-width:640px;}
th{
  text-align:left;padding:13px 16px;font-size:.74rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted);font-weight:700;
  border-bottom:1px solid var(--line);background:var(--bg-soft);
}
td{padding:14px 16px;border-bottom:1px solid var(--line);color:var(--ink);vertical-align:middle;}
tr:last-child td{border-bottom:none;}
tbody tr:hover{background:var(--card-2);}
td .sub{display:block;color:var(--muted);font-size:.84rem;}

/* ---------- badges ---------- */
.badge{
  display:inline-block;font-size:.72rem;letter-spacing:.08em;text-transform:uppercase;
  padding:5px 11px;border-radius:999px;border:1px solid var(--line);color:var(--muted);
}
.badge-ok{color:var(--ok);border-color:rgba(143,214,196,.4);}
.badge-warn{color:var(--warn);border-color:rgba(227,200,138,.4);}
.badge-danger{color:var(--danger);border-color:rgba(232,140,125,.4);}

/* ---------- admin shell ---------- */
.admin{display:grid;grid-template-columns:230px 1fr;min-height:100vh;}
.side{background:var(--card);border-right:1px solid var(--line);padding:20px 0;}
.side .brand{padding:0 20px 22px;}
.side-group{padding:0 12px;margin-bottom:20px;}
.side-group h5{
  font-family:'Karla',sans-serif;font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted);padding:0 8px 8px;font-weight:700;
}
.side a{
  display:flex;align-items:center;gap:10px;padding:9px 12px;border-radius:var(--r-sm);
  color:var(--muted);font-size:.93rem;
}
.side a:hover{background:var(--card-2);color:var(--ink);}
.side a.on{background:var(--bg-soft);color:var(--ink);}
.side a .tick{width:5px;height:5px;border-radius:50%;background:var(--glow);margin-left:auto;}
.main{padding:26px 30px 70px;min-width:0;}
.main-head{display:flex;align-items:center;gap:16px;margin-bottom:26px;flex-wrap:wrap;}
.main-head h1{font-size:1.6rem;}
.main-head .right{margin-left:auto;display:flex;gap:10px;}

/* ---------- stat tiles ---------- */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:28px;}
.stat{background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);padding:18px 20px;}
.stat .n{font-family:'Newsreader',serif;font-size:1.9rem;line-height:1.1;}
.stat .l{font-size:.8rem;color:var(--muted);margin-top:3px;}

/* ---------- content / item rows ---------- */
.item-row{
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:16px 18px;margin-bottom:10px;
  display:grid;grid-template-columns:auto 1fr auto;gap:16px;align-items:center;
}
/* Numbered circle, matching the brand dot in the corner.
   The gradient is the brand one shifted darker so white numerals stay legible.
   On the bright #8FD6C4 the brand dot uses, white sits at about 1.7:1 contrast,
   which is unreadable. At this depth it is roughly 5:1. */
.item-n{
  width:26px;height:26px;border-radius:50%;flex:none;
  background:radial-gradient(circle at 38% 35%, #4FA893 0%, #2E6B5C 55%, #245448 100%);
  color:#fff;
  font-family:'Karla',system-ui,sans-serif;
  font-style:normal;
  font-weight:700;
  font-size:.8rem;
  line-height:1;
  display:grid;
  place-items:center;
  text-align:center;
}
.item-row h4{font-size:1.02rem;font-style:italic;}
.item-row p{color:var(--muted);font-size:.88rem;margin-top:2px;}
.drag{color:var(--muted);cursor:grab;font-size:1.1rem;}

/* ---------- video ---------- */
.video-frame{
  position:relative;aspect-ratio:16/9;width:100%;
  background:var(--bg-soft);border:1px solid var(--line);border-radius:var(--r-lg);
  display:grid;place-items:center;overflow:hidden;
}
.video-frame .play{
  width:70px;height:70px;border-radius:50%;background:var(--glow);color:var(--on-glow);
  display:grid;place-items:center;font-size:1.5rem;
}
.video-frame .stub{position:absolute;bottom:12px;left:14px;font-size:.76rem;color:var(--muted);}

/* ---------- empty state ---------- */
.empty{text-align:center;padding:56px 24px;}
.empty h3{font-size:1.25rem;font-style:italic;margin:16px 0 8px;}
.empty p{color:var(--muted);max-width:40ch;margin:0 auto 22px;}

/* ---------- misc ---------- */
.note{color:var(--muted);font-size:.86rem;}
.sep{border:0;border-top:1px solid var(--line);margin:26px 0;}
.stack-8>*+*{margin-top:8px;}
.stack-16>*+*{margin-top:16px;}
.row{display:flex;gap:12px;align-items:center;flex-wrap:wrap;}
.right{margin-left:auto;}
.foot{border-top:1px solid var(--line);padding:22px 0 50px;color:var(--muted);font-size:.84rem;}

.alert{border-radius:var(--r);padding:13px 16px;font-size:.9rem;border:1px solid var(--line);background:var(--bg-soft);}
.alert-ok{border-color:rgba(143,214,196,.35);color:var(--ok);}
.alert-warn{border-color:rgba(227,200,138,.35);color:var(--warn);}
.alert-danger{border-color:rgba(232,140,125,.35);color:var(--danger);}

@media (max-width:900px){
  .grid-2,.grid-3,.grid-side{grid-template-columns:1fr;}
  .stats{grid-template-columns:repeat(2,1fr);}
  .admin{grid-template-columns:1fr;}
  .side{border-right:0;border-bottom:1px solid var(--line);}
  .main{padding:22px 18px 60px;}
}
@media (max-width:560px){
  .otp input{width:44px;height:54px;font-size:1.25rem;}
  .topbar nav{gap:14px;font-size:.88rem;}

  /* The three column row (numeral, text, meta) collapsed to two columns, which
     dropped the meta span into the numeral column and left a 97px hole between
     the numeral and the title. Numeral and text now share row one, and the meta
     spans its own row aligned to the same left edge as the title. */
  .item-row{
    grid-template-columns:auto 1fr;
    align-items:start;
    row-gap:10px;
    column-gap:14px;
  }
  /* Meta spans its own row, right aligned, so duration and badge sit against
     the card edge rather than floating under the title. */
  .item-row > :last-child{
    grid-column:1 / -1;
    justify-content:flex-end;
    /* justify-self as well as justify-content: an unready item's last child is a
       bare badge rather than a flex wrapper, so without this it stretches to the
       full card width instead of sitting at the right edge. */
    justify-self:end;
  }
  /* Roman numerals vary in width. Right aligning them means i, ii and iii all
     end at the same point and sit a consistent distance from the title, instead
     of each being centred in its box and leaving a different gap. */
  /* Circle stays a fixed 26px, so nothing to re-align on mobile. */
  .item-n{margin-top:2px;}

  .page{padding:20px 0 64px;}
  .page-head{margin-bottom:22px;}

  /* The "In this toolkit" list is a set of standalone navigation links, so each
     needs a real tap height. Links inside a sentence are left alone: padding
     them would break the line, and WCAG exempts inline text links. */
  .card .stack-8 > div > a{display:inline-block;padding:9px 0;}
}

/* ---------- audio stage ----------
   Audio needs no 16:9 box. The breathing orb becomes the focal point, which
   suits eyes-closed use far better than a black rectangle. */
.audio-stage{
  background:linear-gradient(160deg,var(--card) 0%,var(--bg-soft) 100%);
  border:1px solid var(--line);border-radius:var(--r-xl);
  padding:52px 40px;text-align:center;
}
.audio-stage audio{width:100%;margin-top:28px;}
.audio-hint{
  font-size:.8rem;color:var(--muted);letter-spacing:.14em;
  text-transform:uppercase;margin-top:16px;
}

/* ---------- mobile navigation ----------
   At narrow widths the brand and three nav items on one row wrapped mid-phrase:
   "Calm the / Moment", "My / library", "Sign / out". Horizontal overflow checks
   never caught it, because wrapping is what the layout does *instead* of
   overflowing. Fixed by stacking the two groups and forbidding wrap inside any
   individual label. */
@media (max-width:620px){
  .topbar-in{
    flex-direction:column;
    align-items:stretch;
    gap:12px;
    /* padding-block only. The shorthand would wipe the horizontal gutter that
       .wrap provides and leave nav labels touching the screen edge. */
    padding-block:13px;
  }
  .brand{
    font-size:1.05rem;
    white-space:nowrap;
  }
  .topbar nav{
    margin-left:0;
    width:100%;
    justify-content:space-between;
    gap:10px;
    font-size:.9rem;
  }
  /* No label may break across lines. This is the actual bug. */
  .topbar nav a,
  .topbar nav button,
  .topbar nav form{
    white-space:nowrap;
    flex:0 0 auto;
  }
  /* The avatar earns nothing on a phone and it was stealing width. */
  .topbar .avatar{display:none;}
}

/* ---------- item summary and detail ----------
   The list gets one scannable line. A long description used to render in full
   there, which pushed a five item list to several screens. Clamped in CSS as a
   backstop in case a long value reaches the field despite the 200 char limit. */
.item-summary{
  display:-webkit-box;
  -webkit-line-clamp:2;
  -webkit-box-orient:vertical;
  overflow:hidden;
}
/* The item page is where the full text belongs, so it gets reading measure. */
.item-detail{max-width:62ch;}
.item-detail p{color:var(--muted);margin-bottom:14px;}
.item-detail p:last-child{margin-bottom:0;}

/* ---------- audio player ----------
   No video surface. Vimeo always renders a thumbnail and a play overlay, which
   contradicts "screen can be off" and competes with the orb, so the iframe is
   collapsed and driven through the player API instead. */
.audio-orb-wrap{display:flex;justify-content:center;}
.audio-orb{width:130px;height:130px;}

/* The orb breathes only while audio is playing. Animating a stopped player reads
   as though something is running. */
@media (prefers-reduced-motion:no-preference){
  .audio-orb--playing{animation:breathe 10s ease-in-out infinite;}
}

/* Present in the DOM and playable, never visible. */
.audio-embed{height:0;overflow:hidden;}
.audio-embed iframe{width:1px;height:1px;border:0;opacity:0;pointer-events:none;}

.audio-controls{margin-top:34px;}
.audio-track{
  height:5px;background:var(--line);border-radius:999px;position:relative;cursor:pointer;
}
.audio-track:focus-visible{outline:2px solid var(--glow);outline-offset:6px;}
.audio-track i{
  position:absolute;left:0;top:0;height:100%;width:0;
  background:var(--glow);border-radius:999px;
}
.audio-track b{
  position:absolute;left:0;top:50%;transform:translate(-50%,-50%);
  width:14px;height:14px;border-radius:50%;background:var(--glow);
}
.audio-times{
  display:flex;justify-content:space-between;margin-top:10px;
  font-size:.84rem;color:var(--muted);font-variant-numeric:tabular-nums;
}
.audio-buttons{display:flex;gap:14px;align-items:center;justify-content:center;margin-top:22px;}
.icon-btn{
  width:46px;height:46px;border-radius:50%;border:1px solid var(--line);
  background:transparent;color:var(--muted);display:grid;place-items:center;
  cursor:pointer;font:700 .85rem 'Karla',sans-serif;
}
.icon-btn:hover{background:var(--card-2);color:var(--ink);}
.play-big{
  width:72px;height:72px;border-radius:50%;background:var(--glow);color:var(--on-glow);
  border:0;display:grid;place-items:center;font-size:1.4rem;cursor:pointer;
}
.play-big:hover{background:#A8E2D2;}
.audio-foot{margin-top:24px;}
