/* ==========================================================================
   Ocademy - members area stylesheet
   Palette and typography taken from ocademyglobal.com: Lato, #03BEE6 accent,
   #487C9F primary, #18BA60 success, #393E41 body, #1E1C1C header.
   The header stays dark in every state because the only logo is white.
   ========================================================================== */

:root{
  /* surfaces */
  --bg:#FFFFFF;
  --bg-soft:#F5F7F8;
  --card:#FFFFFF;
  --card-2:#F0F3F5;
  --line:#E2E5E7;

  /* text */
  --ink:#393E41;
  --muted:#7E8085;

  /* primary. #487C9F is the brand button colour and carries white at 4.5:1.
     --glow-deep is the text-safe variant at 6.1:1, used for links and hovers. */
  --glow:#487C9F;
  --glow-deep:#3A6681;
  --on-glow:#FFFFFF;

  /* brand cyan. 2.1:1 on white, so it is a fill and never text. */
  --accent:#03BEE6;

  /* status. Fill colours are the brand values; text colours are darkened to
     clear AA on a light background, which the brand values do not. */
  --ok:#15803D;      --ok-fill:#18BA60;  --ok-bg:#E9F7EF; --ok-line:#BFE6CE;
  --warn:#8A6D00;    --warn-bg:#FDF6E3;  --warn-line:#EBDDB0;
  --danger:#C62828;  --danger-bg:#FDECEA;--danger-line:#F3C9C4;

  /* header, dark in every variant so the white logo works */
  --topbar-bg:#1E1C1C;
  --topbar-ink:#FFFFFF;
  --topbar-muted:#C9CFD2;

  --r-sm:10px; --r:12px; --r-lg:16px; --r-xl:20px;
  --shadow:0 1px 3px rgba(20,25,28,.07),0 1px 2px rgba(20,25,28,.04);
}

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

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

/* ---------- brand ---------- */
.brand{display:inline-flex;align-items:center;gap:11px;font-family:'Lato',system-ui,sans-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%,#5BD9F5 0%,var(--accent) 55%,#029BBC 100%);
}
.dot-lg{width:56px;height:56px;box-shadow:0 0 28px rgba(3,190,230,.28);}
/* Used by .audio-orb--playing on the player. */
@keyframes breathe{0%{transform:scale(.85);}40%{transform:scale(1.06);}100%{transform:scale(.85);}}

/* Wordmark on light panels. The signed-out pages have no topbar, so this is the
   only branding a visitor sees before they have an account. */
.brand-lockup{display:block;width:auto;max-width:min(170px,62vw);height:auto;}

/* ---------- 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(--topbar-bg);border-bottom:1px solid var(--topbar-bg);}
.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(--topbar-muted);}
.topbar nav a:hover{color:var(--topbar-ink);}
.topbar nav a.on{color:var(--topbar-ink);font-weight:700;box-shadow:inset 0 -2px 0 var(--accent);}
.topbar .brand img{height:24px;width:auto;display:block;max-width:100%;}
.avatar{
  width:32px;height:32px;border-radius:50%;background:var(--accent);
  border:1px solid var(--accent);display:grid;place-items:center;
  font-size:.76rem;font-weight:700;color:#06232B;
}
.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;box-shadow:var(--shadow);}
.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 'Lato',sans-serif;
  background:var(--glow);color:var(--on-glow);border:none;border-radius:var(--r);
  cursor:pointer;transition:background .15s ease;
}
.btn:hover{background:var(--glow-deep);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:var(--danger-bg);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 'Lato',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:var(--muted);}
.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);background:var(--ok-bg);border-color:var(--ok-line);}
.badge-warn{color:var(--warn);background:var(--warn-bg);border-color:var(--warn-line);}
.badge-danger{color:var(--danger);background:var(--danger-bg);border-color:var(--danger-line);}

/* ---------- 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:'Lato',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:'Lato',system-ui,sans-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. It carries white numerals, so it uses the primary rather
   than the #03BEE6 brand cyan: white on that cyan is 1.9:1 and unreadable.
   On this gradient white sits at roughly 4.9:1. */
.item-n{
  width:26px;height:26px;border-radius:50%;flex:none;
  background:radial-gradient(circle at 38% 35%, #5C90B3 0%, #487C9F 55%, #3A6681 100%);
  color:#fff;
  font-family:'Lato',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;}
.item-row p{color:var(--muted);font-size:.88rem;margin-top:2px;}
.drag{color:var(--muted);cursor:grab;font-size:1.1rem;}

/* ---------- sections ---------- */
.section-block{margin-bottom:34px;}
.section-block:last-child{margin-bottom:0;}
.section-head{margin:0 0 14px;}
.section-head h2{font-size:1.15rem;margin-bottom:3px;}
/* The rule sits under the heading rather than above the block, so the first
   section does not get a stray line directly beneath the page header. */
.section-head{border-bottom:1px solid var(--line);padding-bottom:10px;}

/* ---------- document ---------- */
.doc-frame{
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:40px 24px;text-align:center;box-shadow:var(--shadow);
}
.doc-icon{
  display:inline-grid;place-items:center;width:64px;height:64px;border-radius:var(--r);
  background:var(--glow);color:var(--on-glow);
  font-size:.82rem;font-weight:700;letter-spacing:.08em;margin-bottom:16px;
}
.doc-name{font-weight:700;margin-bottom:2px;word-break:break-word;}
.doc-size{margin-bottom:20px;}

/* ---------- 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;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:var(--ok-line);background:var(--ok-bg);color:var(--ok);}
.alert-warn{border-color:var(--warn-line);background:var(--warn-bg);color:var(--warn);}
.alert-danger{border-color:var(--danger-line);background:var(--danger-bg);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. A video player 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 'Lato',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:var(--glow-deep);}
.audio-foot{margin-top:24px;}
