*{box-sizing:border-box}
/* Theme accent tokens. Defaults are the ClassPixie purple (unchanged for every
   existing page). A page sets <html data-theme="…"> to re-tint the wordmark and
   accents — e.g. SolidCore's monochrome white below. Structural grays stay shared. */
:root{--wm-a:#7C5CFF;--wm-b:#c6acff;--accent:#7C5CFF;--bg:#0C0B10;
  --font-heading:"Instrument Serif",serif;--font-body:"Outfit",sans-serif}
/* SolidCore's brand is monochrome white (not coral) — accent + wordmark go white. */
[data-theme=solidcore]{--wm-a:#ffffff;--wm-b:#cfcfcf;--accent:#ffffff}
body{font-family:var(--font-body);font-weight:300;background:var(--bg);color:#EDEBF2;
     max-width:30rem;margin:0 auto;padding:2rem 1.5rem calc(5rem + env(safe-area-inset-bottom));line-height:1.6;font-size:16px;-webkit-font-smoothing:antialiased}
/* Ambient purple glow orb — a rich dark-purple light that slowly drifts around
   the page background like a spotlight behind the content. Large radial gradient
   on an oversized pseudo-element, animated via transform (GPU-composited). */
body::before{content:"";position:fixed;top:-40%;left:-40%;width:180%;height:180%;z-index:-1;pointer-events:none;
  background:radial-gradient(circle at center,
    rgba(140,60,255,.25) 0%,
    rgba(100,40,220,.15) 15%,
    rgba(80,30,180,.06) 35%,
    transparent 55%);
  animation:ambient-drift 25s ease-in-out infinite}
@keyframes ambient-drift{
  0%{transform:translate(0%,0%)}
  20%{transform:translate(25%,15%)}
  40%{transform:translate(10%,35%)}
  60%{transform:translate(-20%,20%)}
  80%{transform:translate(-10%,-10%)}
  100%{transform:translate(0%,0%)}}
@media (prefers-reduced-motion:reduce){body::before{animation:none;transform:translate(0,0)}}
/* Auth / focused pages (no bottom tab bar): branding stays pinned to the top,
   while the sign-in block (.authmain) centers vertically in the space below it. */
body:not(:has(.tabbar)){min-height:100vh;min-height:100dvh;display:flex;flex-direction:column;padding-bottom:calc(.75rem + env(safe-area-inset-bottom))}
.authmain{margin:auto 0}
.brandtop{display:inline-block;align-self:flex-start;width:fit-content;font-weight:500;letter-spacing:.01em;font-size:.98rem;color:var(--accent);margin:0 0 .55rem;border-bottom:0}
.brandtop:hover{opacity:.82;border-bottom:0}
.brandspark{width:1.12em;height:1.12em;vertical-align:-.24em;margin-left:.34em}
/* Gradient wordmark + a soft sheen that floats around the WHOLE word. A glowing
   orb (radial highlight) drifts on a slow wandering path over the base gradient
   (deep purple "Class" → lighter lavender "Pixie"), all clipped to the text. The
   .cl/.pi spans just inherit the transparent fill. */
.brandtop,.px{background-image:radial-gradient(closest-side,rgba(255,255,255,.55),rgba(255,255,255,0)),linear-gradient(95deg,var(--wm-a),var(--wm-b));
  background-size:46% 260%,100% 100%;background-repeat:no-repeat;background-position:8% 35%,0 0;
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;
  animation:pixie-sheen 11s ease-in-out infinite}
@keyframes pixie-sheen{
  0%,100%{background-position:6% 32%,0 0}
  22%{background-position:40% 72%,0 0}
  44%{background-position:72% 24%,0 0}
  68%{background-position:94% 66%,0 0}
  86%{background-position:48% 42%,0 0}}
@media (prefers-reduced-motion:reduce){.brandtop,.px{animation:none}}
.pitch{margin:3rem 0 0;font-size:.9rem;line-height:1.6;color:#9a9a9a}
.lead{margin:.3rem 0 1.6rem;font-size:20px;line-height:1.6;color:#fff;max-width:38em}
@media (max-width:640px){.lead{font-size:17px}}
/* Landing dashboard preview — a framed, non-interactive showcase of the real
   .clx cells. The frame + a faint top fade signal "this is the app". */
.preview{border:1px solid #1c1c1c;border-radius:.7rem;background:#0c0c0c;padding:.2rem 1.1rem 1.2rem;margin:.5rem 0 0}
.preview-h{font-weight:500;font-size:.95rem;color:#fff;letter-spacing:.01em;margin:1.5rem 0 .1rem}
.preview-h:first-child{margin-top:1rem}
.preview .clx:first-of-type{border-top:0}
.px{color:var(--accent);font-weight:500;white-space:nowrap}
/* "Coming soon" pill — reads the themed accent so it matches whatever provider. */
.soon{display:inline-block;font-size:.62rem;font-weight:500;letter-spacing:.08em;color:var(--accent);border:1px solid var(--accent);border-radius:1rem;padding:.34rem .72rem;margin:.1rem 0 1.3rem}
/* Provider switcher (only shown to users who've linked 2+ providers). */
.provider-switch{display:flex;gap:.5rem;margin:0 0 1.4rem}
.ps-tab{font-size:.75rem;font-weight:500;letter-spacing:.04em;padding:.4rem .8rem;border:1px solid #2c2c2c;border-radius:1rem;color:#9a9a9a;border-bottom:1px solid #2c2c2c}
.ps-tab:hover{border-color:var(--accent);color:#EDEBF2}
.ps-tab.on{border-color:var(--accent);color:var(--accent)}
/* SolidCore link: SMS-vs-email delivery choice. */
.otp-choice{display:flex;gap:1.1rem;margin:.7rem 0 .2rem;font-size:.82rem;color:#bbb;text-transform:none;letter-spacing:0}
.otp-choice label{display:flex;align-items:center;gap:.35rem;cursor:pointer}
.otp-choice input{width:auto;margin:0}
/* Compact inline Book / Waitlist button on a SolidCore class row. */
.bookbtn{width:auto;margin:0;padding:.42rem .95rem;background:var(--accent);color:var(--bg);border:1px solid var(--accent);border-radius:1rem;font-family:var(--font-body);font-size:15px;font-weight:500;letter-spacing:.02em;cursor:pointer}
.bookbtn:hover{opacity:.85}
/* Booked/Waitlisted status shown next to a Cancel button in a class action cell. */
.act-state{margin-right:.55rem;font-size:.72rem;white-space:nowrap}
.brand{font-weight:500;letter-spacing:.2em;font-size:.9rem;margin:0 0 .35rem;color:#fff}
.brandsub{letter-spacing:.1em;font-size:.6rem;color:#7a7a7a;margin:0 0 1.5rem}
h2{font-weight:500;letter-spacing:.02em;font-size:.85rem;color:#8a8a8a;margin:2.75rem 0 .85rem}
label{display:block;letter-spacing:.04em;font-size:.75rem;color:#8a8a8a;margin:1.1rem 0 .3rem}
input{width:100%;background:transparent;border:0;border-bottom:1px solid #2c2c2c;color:#fff;
      padding:.6rem 0;font-family:var(--font-body);font-size:16px;letter-spacing:.01em}
input::placeholder{color:#5a5a5a;text-transform:none;letter-spacing:0}
input:focus{outline:0;border-color:#fff}
button{width:100%;margin-top:1.9rem;background:#fff;color:#000;border:1px solid #fff;
       padding:.9rem;font-family:var(--font-body);font-weight:500;letter-spacing:.04em;font-size:15px;cursor:pointer;transition:opacity .15s}
button:hover{opacity:.82}
.ghost{width:auto;margin:0;background:transparent;color:#EDEBF2;border:1px solid #333;
       padding:.5rem .95rem;letter-spacing:.04em;font-size:15px}
.ghost:hover{border-color:#fff;opacity:1}
a{color:#fff;text-decoration:none;border-bottom:1px solid #555}
a:hover{border-color:#fff}
.muted{color:#777;font-size:14px}
.err{color:#ff6b6b;font-size:.84rem;letter-spacing:.02em}
.ok{color:#5ad19b}
.card{border:1px solid #1c1c1c;background:#101010;padding:1.15rem 1.2rem;margin:.85rem 0}
.card b{font-weight:500;letter-spacing:.02em}
/* Provider hub (home page): two wordmark tiles → /equinox and /solidcore. */
.provtiles{display:grid;grid-template-columns:1fr 1fr;gap:1rem;margin:1.7rem 0 1.2rem}
@media (max-width:560px){.provtiles{grid-template-columns:1fr}}
.provtile{display:flex;flex-direction:column;gap:.55rem;justify-content:center;min-height:8.5rem;
  padding:1.5rem 1.4rem;border:1px solid #1c1c1c;background:#101010;border-radius:.5rem;
  text-decoration:none;transition:border-color .15s,background .15s}
.provtile:hover{background:#141414}
.provtile.eqx:hover{border-color:#e6e6e6}
.provtile.sc:hover{border-color:#e6e6e6}
.provwm{font-size:1.5rem;line-height:1}
.eqxwm{color:#fff;font-weight:500;letter-spacing:.12em}
.scwm{color:#fff;font-weight:500;letter-spacing:.01em}
.provsub{font-size:13px;letter-spacing:.04em;color:#8a8a8a}
/* SolidCore wordmark logo — the brand's bracketed lowercase mark, monochrome
   white (SolidCore's brand color); scales via font-size on .sclogo. */
.schero{margin:.2rem 0 .4rem}
.sclogo{font-weight:500;font-size:2.3rem;line-height:1;letter-spacing:-.015em;color:#fff}
.sclogo .sccore{color:#fff;font-weight:400}
.invite-code{display:inline-block;margin-top:.6rem;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:1.05rem;letter-spacing:.12em;color:#c9a9ff;background:#161018;border:1px solid #2a2233;
  border-radius:6px;padding:.35rem .6rem}
s.invite-code{color:#6c6470;border-color:#241f29}
.row{display:flex;justify-content:space-between;align-items:center}
form.inline{display:inline}
/* Settings switch (e.g. Google Calendar auto-add). The whole row is a submit
   <button role=switch> — works with JS off (form POST); app.js flips it
   optimistically before swapping in the server-confirmed card. */
.switch{width:100%;margin:.85rem 0 0;padding:0;background:transparent;border:0;cursor:pointer;
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  font:inherit;text-transform:none;letter-spacing:0;color:#EDEBF2}
.switch:hover{opacity:1}
.switch-label{font-size:.92rem;text-align:left}
.switch-track{flex:0 0 auto;width:2.7rem;height:1.55rem;border-radius:1rem;background:#383838;
  position:relative;transition:background .18s ease}
.switch-knob{position:absolute;top:.2rem;left:.2rem;width:1.15rem;height:1.15rem;border-radius:50%;
  background:#fff;transition:transform .18s ease}
.switch.on .switch-track{background:#7C5CFF}
.switch.on .switch-knob{transform:translateX(1.15rem)}
.switch:focus-visible{outline:none}
.switch:focus-visible .switch-track{box-shadow:0 0 0 3px rgba(124,92,255,.4)}
@media (prefers-reduced-motion:reduce){.switch-track,.switch-knob{transition:none}}
/* Connect (primary) + Unlink (quiet, turns red on hover) actions in the card. */
.connectbtn{display:inline-block;background:#fff;color:#000;border:1px solid #fff;
  padding:.7rem 1.1rem;font-family:var(--font-body);font-weight:500;letter-spacing:.04em;font-size:15px}
.connectbtn:hover{opacity:.82;border-color:#fff}
.unlinkbtn{width:auto;margin:0;padding:0 0 .1rem;background:transparent;color:#888;border:0;
  border-bottom:1px solid #444;font-size:.8rem;text-transform:none;letter-spacing:0;cursor:pointer}
.unlinkbtn:hover{color:#ff6b6b;border-color:#ff6b6b;opacity:1}
ul{list-style:none;padding:0;margin:.5rem 0} li{border-bottom:1px solid #1a1a1a;padding:.65rem 0;font-size:.94rem}
/* ── Schedule (Equinox-style Classes view) ── */
.sched-h{display:flex;justify-content:space-between;align-items:baseline;margin:.2rem 0 1.4rem}
.sched-h h1{margin:0}
/* Section header — sentence case, consistent across dashboard sections. */
/* Primary page heading. Used on the first heading of a page as <h1 class=sect>
   (one H1 per page for SEO) and on later sections as <h2 class=sect>. The class
   selector wins over any bare-tag rule, so h1/h2 render identically — line-height
   is set explicitly here so promoting the tag never changes wrapped-line spacing. */
.sect{font-weight:500;font-size:28px;line-height:1.2;letter-spacing:-.01em;color:#fff;margin:2.6rem 0 .9rem}
@media (max-width:640px){.sect{font-size:22px}}
.sched-h .sect{margin:0}
/* Dashboard sections — stacked on mobile (the 2nd gets a gap), 2-up on desktop. */
.col>.sect{margin:.2rem 0 1rem}
.col+.col>.sect{margin-top:2.6rem}
.daystrip{display:flex;gap:.15rem;overflow-x:auto;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;
          position:sticky;top:0;z-index:20;background:var(--bg);
          margin:0 -1.5rem 1.5rem;padding:.7rem 1.5rem .6rem;scrollbar-width:none;border-bottom:1px solid #1a1a1a}
.daystrip::-webkit-scrollbar{display:none}
.day{flex:0 0 auto;width:2.7rem;text-align:center;border:0;position:relative;z-index:1}
.day:hover{border:0}
.day .dow{display:block;letter-spacing:.02em;font-size:.6rem;color:#777;margin-bottom:.5rem}
.day .dnum{display:inline-flex;align-items:center;justify-content:center;width:2.1rem;height:2.1rem;border-radius:50%;font-size:1rem;color:#cdcdcd;border:1px solid transparent;transition:color .12s}
.day.today .dow{color:#e6e6e6}
.day.today .dnum{border-color:#3a3a3a}
.day.sel .dow{color:#fff}
.day.sel .dnum{background:#7C5CFF;border-color:#7C5CFF;color:#fff}
/* JS slides this purple puck between dates; with it active the per-day fill is
   hidden (the no-JS page keeps the static .sel circle above). */
.daypuck{position:absolute;top:0;left:0;width:2.1rem;height:2.1rem;border-radius:50%;background:#7C5CFF;z-index:0;pointer-events:none}
.daypuck.anim{transition:transform .22s cubic-bezier(.22,.61,.36,1)}
.daystrip.haspuck .day.sel .dnum{background:transparent;border-color:transparent}
/* The day-strip selection is Equinox purple by default; the SolidCore theme tints it white. */
/* White selection needs a DARK number to read (the base rule's white number would
   vanish on the white circle/puck) — invert it, like Equinox's white-on-purple. */
[data-theme=solidcore] .day.sel .dnum{background:var(--accent);border-color:var(--accent);color:var(--bg)}
[data-theme=solidcore] .daypuck{background:var(--accent)}
.filterbar{display:flex;gap:.7rem;align-items:center;margin:0 0 1.4rem;flex-wrap:wrap}
.filterbar input{flex:1;min-width:7rem}
.filterbar .pill{margin-top:0}
.toggle{display:flex;align-items:center;gap:.35rem;white-space:nowrap;letter-spacing:.02em;font-size:13px;color:#777;margin:0}
.toggle input{width:auto}
/* Swipe carousel: 3 day-panels in a row; the track is shifted to show the
   middle one, and app.js drags it between days. Only the current pane sets the
   carousel height; the off-screen neighbours are capped to 0 so a busier
   adjacent day can't inflate the page with a screenful of empty scroll (their
   content still overflows for the drag preview, clipped to the current height
   by .swipe's overflow:hidden). */
.swipe{overflow:hidden;touch-action:pan-y;margin:0 -1.5rem}
.swipe-track{display:flex;align-items:flex-start;transform:translateX(-100%);will-change:transform}
.swipe-track.anim{transition:transform .22s cubic-bezier(.22,.61,.36,1)}
.swipe-pane{flex:0 0 100%;min-width:100%;padding:0 1.5rem}
.swipe-pane:not(.cur){max-height:0}
.clx{border-top:1px solid #1c1c1c;padding:1.15rem 0}
.clx-time{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;
          font-size:.92rem;color:#cfcfcf;margin-bottom:.5rem;letter-spacing:.01em}
.clx-row{display:flex;justify-content:space-between;align-items:center;gap:1rem}
.clx-name{font-size:17px;font-weight:500;line-height:1.2;letter-spacing:.005em}
/* Equinox name badge ("NEW"/"UPDATED") shown beside the class name. Structural
   styling only — the label colour comes inline from the API's per-tag hex. */
.ctag{font-size:.58rem;font-weight:500;letter-spacing:.06em;
  vertical-align:.18em;margin-inline:.1em .4em;color:#8a8a8a}
.clx-meta{color:#777;font-size:.85rem;margin-top:.3rem}
/* Substitute-instructor tag in the meta row — the sub's name shows; "(sub)" is
   gold so it reads as a heads-up that the usual instructor isn't teaching. */
.sub{color:#c9a24a;font-weight:500}
/* Loading shimmer for the "N signed up" count while it's fetched after paint;
   reserves the count's width so nothing jumps when it lands. */
.skel{display:inline-block;width:2.4em;height:1em;border-radius:.5em;vertical-align:-.22em;
      background:linear-gradient(90deg,#181818,#2a2a2a,#181818);background-size:200% 100%;animation:skel 1.1s ease-in-out infinite}
@keyframes skel{0%{background-position:200% 0}100%{background-position:-200% 0}}
.badge{display:inline-block;font-size:.55rem;letter-spacing:.06em;font-weight:500;border:1px solid #4a4a4a;color:#cfcfcf;padding:.12rem .32rem;border-radius:3px;vertical-align:middle;position:relative;top:-.1rem;margin-right:.45rem}
.clx-act{display:flex;flex-direction:column;align-items:flex-end;gap:.5rem;min-width:6.5rem;text-align:right}
.clx-status{display:flex;flex-direction:column;align-items:flex-end;gap:.18rem}
.weekly{color:#8a8a8a;font-size:.56rem;letter-spacing:.04em;white-space:nowrap}
.pill{width:auto;margin:0;background:#262626;color:#fff;border:1px solid #2e2e2e;border-radius:2rem;
      padding:.6rem 1.1rem;font-size:15px;letter-spacing:.02em;font-weight:500;white-space:nowrap}
.pill:hover{background:#333;opacity:1}
.repeat{width:auto;margin:0;padding:0;background:none;border:0;color:#777;
        font-size:13px;letter-spacing:.02em;font-weight:400}
.repeat:hover{color:#fff;opacity:1;background:none}
.skipweek{width:auto;margin:.2rem 0 0;padding:0;background:none;border:0;color:#777;
        font-size:13px;letter-spacing:.02em;font-weight:400;display:block}
.skipweek:hover{color:#c9a24a;opacity:1;background:none}
.horizon{width:auto;margin:0 .35rem 0 0;padding:.15rem .3rem;background:#1c1c1c;color:#aaa;
        border:1px solid #2e2e2e;border-radius:.3rem;font-size:.56rem;letter-spacing:.04em;vertical-align:middle}
.booked{color:#5ad19b;font-size:.7rem;letter-spacing:.06em;white-space:nowrap;text-align:center}
.cancelpill{width:auto;margin:0;background:transparent;color:#b98a8a;border:1px solid #3a2a2a;border-radius:2rem;
      padding:.6rem 1.1rem;font-size:15px;letter-spacing:.02em;font-weight:500;white-space:nowrap}
.cancelpill:hover{border-color:#ff6b6b;color:#ff6b6b;opacity:1;background:none}
.queued{color:#c9a24a;font-size:.7rem;letter-spacing:.06em}
/* Themed confirm dialog (cancel / skip), shown by app.js. Matches the dark
   editorial palette; no system chrome. */
.modal-ov{position:fixed;inset:0;z-index:100;display:flex;align-items:center;justify-content:center;
          padding:1.5rem;background:rgba(0,0,0,.66);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);
          animation:modalin .14s ease-out}
@keyframes modalin{from{opacity:0}to{opacity:1}}
.modal{width:100%;max-width:20rem;background:#141414;border:1px solid #2a2a2a;border-radius:.5rem;
       padding:1.4rem 1.3rem 1.2rem;box-shadow:0 1.5rem 3rem rgba(0,0,0,.5)}
.modal-msg{margin:0 0 1.3rem;font-size:.9rem;line-height:1.5;color:#EDEBF2;letter-spacing:.01em}
.modal-acts{display:flex;gap:.7rem;justify-content:flex-end}
.modal-acts button{width:auto;margin:0;padding:.6rem 1.1rem;font-size:15px;letter-spacing:.02em;
                   font-weight:500;border-radius:2rem}
.modal-keep{background:transparent;color:#EDEBF2;border:1px solid #333}
.modal-keep:hover{border-color:#fff;opacity:1;background:none}
.modal-go{background:transparent;color:#ff6b6b;border:1px solid #5a3030}
.modal-go:hover{border-color:#ff6b6b;background:rgba(255,107,107,.08);opacity:1}
/* "Happening now" — a class in progress; the dot gently pulses to read as live. */
.now{color:#5ad19b;font-size:.7rem;letter-spacing:.06em;white-space:nowrap;animation:nowpulse 1.8s ease-in-out infinite}
@keyframes nowpulse{0%,100%{opacity:1}50%{opacity:.5}}
/* Filter sheet + active-filter pills */
/* Filter button + active pills share one wrapping line; opening the filter
   makes the <details> span the full width so its form isn't squeezed. */
.filterrow{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;margin:0 0 1.3rem}
.filters{margin:0}
.filters[open]{flex:1 1 100%}
.filters>summary{list-style:none;display:inline-flex;align-items:center;gap:.4rem;cursor:pointer}
.filters>summary::-webkit-details-marker{display:none}
.fcount{display:inline-flex;align-items:center;justify-content:center;min-width:1.15rem;height:1.15rem;
        background:#7C5CFF;color:#fff;border-radius:1rem;font-size:.6rem;padding:0 .35rem}
.filterform{display:flex;flex-direction:column;gap:1rem;margin-top:.9rem;padding:1.1rem;
            background:#141414;border:1px solid #242424;border-radius:.9rem}
.fld{display:flex;flex-direction:column;gap:.4rem;letter-spacing:.02em;
     font-size:13px;color:#888}
.fld select,.fld input{font:inherit;font-family:var(--font-body);letter-spacing:normal;color:#ececec;
     background:#1d1d1d;border:1px solid #333;border-radius:.55rem;padding:.6rem .65rem;width:100%}
.fld select[multiple]{min-height:9rem;padding:.3rem}
.fld select[multiple] option{padding:.4rem .45rem;border-radius:.4rem;color:#ddd}
.fld select[multiple] option:checked{background:#7C5CFF;color:#fff}
.factions{display:flex;align-items:center;gap:1rem;margin-top:.1rem}
.fpill{display:inline-flex;align-items:center;background:#202020;border:1px solid #2e2e2e;color:#e6e6e6;
       border-radius:2rem;padding:.32rem .75rem;font-size:.8rem}
/* The home/default-gym pill — muted, so it reads as "what you're seeing by
   default" rather than an active filter selection. */
.fpill.home{background:transparent;border-color:#2a2a2a;color:#8f8f8f}
.clearall{color:#9a9a9a;font-size:.8rem;white-space:nowrap}
.clearall:hover{color:#fff}
/* Bottom tab bar (logged-in pages). Pinned to the bottom of the phone column. */
.tabbar{position:fixed;left:50%;transform:translateX(-50%);bottom:0;width:100%;max-width:30rem;z-index:30;
        display:flex;background:rgba(12,11,16,.93);backdrop-filter:blur(10px);border-top:1px solid #1c1c1c;
        padding:.55rem 0 calc(.55rem + env(safe-area-inset-bottom))}
.tab{flex:1;display:flex;flex-direction:column;align-items:center;gap:.25rem;border:0;
     font-family:var(--font-body);color:#6a6a6a;font-size:13px;letter-spacing:.02em;font-weight:500}
.tab:hover{border:0;color:#9a9a9a}
.tab.on{color:#fff}
.tab svg{width:1.45rem;height:1.45rem;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
/* ── Desktop: the bottom tab bar becomes a left sidebar, content sits beside it.
   The content column keeps its 1.5rem padding so the schedule's full-bleed day
   strip still lines up. ── */
@media (min-width:56rem){
  body{max-width:56rem;margin:0 0 0 14rem;padding:2.75rem 1.5rem 3rem}
  /* Dashboard: Upcoming | Weekly side by side. */
  .cols{display:grid;grid-template-columns:1fr 1fr;gap:2.4rem;align-items:start}
  .col+.col>.sect{margin-top:.2rem}
  /* Keep account cards (Settings) at a readable width, not full-bleed. */
  .card{max-width:34rem}
  /* Schedule: keep the class rows + filter tight; the day strip stays full-width
     above them so the calendar still shows a wide range. */
  .swipe .clx{max-width:36rem}
  .filters{max-width:36rem}
  .tabbar{flex-direction:column;justify-content:flex-start;gap:.25rem;
          left:0;top:0;bottom:0;width:14rem;max-width:none;transform:none;
          border-top:0;border-right:1px solid #1c1c1c;background:var(--bg);padding:2.5rem .85rem}
  .tab{flex:0 0 auto;flex-direction:row;justify-content:flex-start;gap:.8rem;
       padding:.7rem .85rem;border-radius:.6rem;font-size:14px;letter-spacing:.02em}
  .tab svg{width:1.2rem;height:1.2rem}
  .tab:hover{background:#131313;color:#cfcfcf}
  .tab.on{background:#161616;color:#fff}
}

/* ─── Admin: activity log (/admin/events) ─────────────────────────────────────
   Operator-only, so it can be denser than the app pages. Scoped selectors
   override the global full-width input/button defaults for an inline filter bar. */
.adminwrap{max-width:none}
.adminwrap h1{font-weight:500;font-size:28px;color:#fff;margin:0 0 1.2rem}
.eventfilters{display:flex;flex-wrap:wrap;gap:.5rem;align-items:center;margin:0 0 1.4rem}
.eventfilters input,.eventfilters select{width:auto;margin:0;padding:.3rem .4rem;
  background:#111;border:1px solid #2c2c2c;border-radius:.3rem;color:#EDEBF2;font-size:.78rem}
.eventfilters button{width:auto;margin:0;padding:.32rem .9rem;font-size:14px;
  letter-spacing:.02em}
.eventfilters .clear{font-size:.72rem;border-bottom:0;color:#777}
.events{width:100%;border-collapse:collapse;font-size:.82rem;line-height:1.45}
/* Mobile-first: collapse the 7-column table into one card per row. The header is
   visually hidden and each cell is labelled inline via its data-label; the real
   table is restored at the desktop breakpoint below. */
.events thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
.events tr{display:block;border:1px solid #1c1c1c;border-radius:.55rem;background:#0d0d0d;
  padding:.3rem .7rem;margin:0 0 .7rem}
.events td{display:flex;gap:.9rem;align-items:baseline;justify-content:space-between;
  text-align:right;padding:.3rem 0;border-bottom:1px solid #141414}
.events tr td:last-child{border-bottom:0}
.events td::before{content:attr(data-label);color:#777;
  letter-spacing:.02em;font-size:13px;font-weight:500;flex:0 0 auto;text-align:left}
.events td[colspan]{display:block;text-align:center;border-bottom:0}
.events td[colspan]::before{content:none}
.events .evt-time{color:#9a9a9a}
.events .evt-action{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;color:#dcdcdc;word-break:break-word}
.events .evt-dur{color:#777}
/* Details stacks full-width so its <details>/<pre> can open below the label. */
.events .evt-detail{display:block;text-align:left}
.events .evt-detail::before{display:block;margin-bottom:.35rem}
/* Desktop: restore the real dense table. This block sits *after* the card rules
   above so its equal-specificity overrides win on source order. */
@media (min-width:56rem){
  .events{font-size:.78rem}
  .events thead{position:static;width:auto;height:auto;clip:auto}
  .events th{text-align:left;letter-spacing:.02em;font-size:13px;
    color:#777;font-weight:500;padding:.3rem .55rem;border-bottom:1px solid #2c2c2c}
  .events tr{display:table-row;border:0;border-radius:0;background:none;padding:0;margin:0}
  .events td{display:table-cell;gap:0;text-align:left;vertical-align:top;
    padding:.4rem .55rem;border-bottom:1px solid #161616}
  .events td::before{content:none}
  .events td[colspan]{display:table-cell;text-align:left}
  .events tr td:last-child{border-bottom:1px solid #161616}
  .events .evt-time{white-space:nowrap}
  .events .evt-dur{white-space:nowrap}
  .events .evt-detail{display:table-cell;max-width:32rem}
  .events .evt-detail::before{display:none}
}
.tag{display:inline-block;font-size:13px;letter-spacing:.02em;
  border:1px solid #333;border-radius:3px;padding:.06rem .3rem;color:#bdbdbd}
.events details summary{cursor:pointer;list-style:none}
.events pre.meta{white-space:pre-wrap;word-break:break-word;background:#0e0e0e;border:1px solid #1c1c1c;
  border-radius:.3rem;padding:.5rem .6rem;margin:.4rem 0 0;max-height:18rem;overflow:auto;
  font-size:.72rem;color:#c4c4c4}
.pager{display:flex;gap:1rem;align-items:center;margin:1.4rem 0 0;font-size:.82rem}
.invitenew{display:flex;flex-wrap:wrap;gap:.5rem;align-items:center;margin:0 0 1rem}
.invitenew input{width:auto;margin:0;padding:.3rem .4rem;background:#111;border:1px solid #2c2c2c;
  border-radius:.3rem;color:#EDEBF2;font-size:.78rem}
.invitenew button{width:auto;margin:0;padding:.32rem .9rem;font-size:14px;letter-spacing:.02em}
.invite-new{margin:0 0 1rem;padding:.55rem .7rem;border:1px solid #2e4b2e;border-radius:.35rem;
  background:#0e150e;font-size:.85rem}
.invite-new code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:1rem;color:#9be29b;letter-spacing:.05em}
.invitefilter{margin:0 0 .9rem;font-size:.78rem;letter-spacing:.06em;color:#777}
.invitefilter a{color:#9a9a9a;border-bottom:0}
.invitefilter a:hover{color:#fff}
.invitefilter b{color:#9be29b;font-weight:500}
/* Analytics KPI grid: auto-fitting stat tiles. */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(8.5rem,1fr));gap:.6rem;margin:0 0 1.6rem}
.stat{border:1px solid #1c1c1c;background:#101010;border-radius:.35rem;padding:.7rem .8rem;display:flex;flex-direction:column;gap:.2rem}
.stat-n{font-size:1.5rem;font-weight:500;color:#fff;line-height:1}
.stat-l{font-size:13px;letter-spacing:.02em;color:#888}
.tag-used{border-color:#3a2a2a;color:#caa}
.tag-open{border-color:#2e4b2e;color:#9be29b}
.adminnav{display:flex;flex-wrap:wrap;gap:.9rem;align-items:baseline;margin:0 0 1.3rem;
  padding:0 0 .7rem;border-bottom:1px solid #1c1c1c;font-size:.82rem}
.adminnav-home{font-weight:500;color:#fff;border-bottom:0;margin-right:.3rem}
.adminnav-link{color:#9a9a9a;border-bottom:0}
.adminnav-link.is-current{color:#9be29b;font-weight:500}
.adminindex{list-style:none;padding:0;margin:0;line-height:1.9}
.adminindex a{font-weight:500}
/* ── Spot / machine selection (Precision Run, cycling, reformer) ── */
a.choosespot{border-bottom:0;display:inline-block}
/* Room map: a sized box; cells are placed by % of the studio canvas. */
.spotmap{position:relative;width:100%;height:0;margin:.4rem 0 1rem;border:1px solid #1c1c1c;background:#0d0d0d;border-radius:.3rem}
.spotmap-in{position:absolute;inset:0}
.spot{position:absolute;width:1.55rem;height:1.55rem;transform:translate(-50%,-50%);
  display:flex;align-items:center;justify-content:center;border-radius:.28rem;
  font-size:.62rem;font-weight:500;letter-spacing:.01em}
.spot.avail{border:1px solid #cfcfcf;color:#e9e9e9}
.spot.unavail{border:1px solid #2b2b2b;color:transparent}
.spotlegend{display:flex;gap:1.1rem;flex-wrap:wrap;margin:0 0 1.4rem;font-size:13px;
  letter-spacing:.02em;color:#8a8a8a}
.spotlegend .lg{display:inline-flex;align-items:center;gap:.4rem}
.spotlegend .sw{width:.85rem;height:.85rem;border-radius:.2rem;display:inline-block}
.spotlegend .sw.sel{background:#fff;border:1px solid #fff}
.spotlegend .sw.avail{border:1px solid #cfcfcf}
.spotlegend .sw.unavail{border:1px solid #2b2b2b}
.spotlist{margin:.2rem 0 1rem}
.spotpick{display:block;margin:0}
.spotrow{width:100%;margin:0;background:transparent;color:#EDEBF2;border:0;border-bottom:1px solid #1a1a1a;border-radius:0;
  display:flex;justify-content:space-between;align-items:center;letter-spacing:.01em;
  font-size:16px;font-weight:500;padding:.95rem .2rem}
.spotrow:hover{background:#141414;opacity:1}
.spotrow .chev{color:#666;font-size:1.2rem}

/* Legal pages (Terms / Privacy) + the small footer linking them. */
.legal-h{font-size:17px;font-weight:500;color:#fff;margin:1.8rem 0 .5rem}
.legal-list{list-style:disc;padding-left:1.2rem;margin:.5rem 0}
.legal-list li{border-bottom:0;padding:.3rem 0;color:#fff;font-size:16px}
/* Pin the footer to the bottom of the screen. It's a body-level sibling (page()
   renders it just after the centered <main class=authmain> / page body). On the
   auth pages authmain's bottom auto-margin already pushes it to the bottom; on
   the logged-in pages (which have no authmain) we make the body a flex column and
   give the footer margin-top:auto so it drops above the fixed tab bar — the
   body's bottom padding already reserves that strip. */
body:has(.legal-foot){min-height:100vh;min-height:100dvh;display:flex;flex-direction:column}
.legal-foot{margin:0;padding-top:2.2rem;font-size:13px;color:#777;text-align:center}
body:has(.tabbar) .legal-foot{margin-top:auto}
.legal-foot a{color:#777;border-bottom-color:#333}
.legal-foot a:hover{color:#fff;border-bottom-color:#fff}
/* Top bar: logo left, sign up right — full-bleed landing pages. */
.topbar{display:flex;justify-content:space-between;align-items:center;padding:2rem 4rem;margin:0 -4rem 0}
.topbar .brandtop{margin-bottom:.1rem;font-size:2.1rem}
.topbar .brandsub{margin-bottom:0;font-size:1rem}
@media (max-width:640px){.topbar{padding:1.2rem 1.5rem;margin:0 -1.5rem 0}}
/* Wide / full-bleed layout for landing pages. */
body.wide{max-width:none;margin:0;padding:0 4rem 3rem;text-align:left}
body.wide .authmain{margin:0}
body.wide .lead{max-width:42rem}
body.wide .provtiles{max-width:none;margin:0}
@media (max-width:640px){body.wide{padding:0 1.5rem 2rem}}
/* ── Landing page ── */
/* Full-bleed sections with generous spacing, Equinox-style. */
.lp-hero{display:flex;flex-direction:column;gap:0;padding:5rem 0 6rem}
@media (max-width:800px){.lp-hero{padding:3rem 0 3rem}}
.hero-lower{display:flex;align-items:stretch;gap:0}
@media (max-width:800px){.hero-lower{flex-direction:column}}
.lp-section{padding:2rem 0}
.lp-inner{max-width:64rem;margin:0 auto}
/* Hero left: lead text below the headline */
.hero-left{flex:1;text-align:left;min-width:0;padding-right:3rem}
.hero-left .lead{text-align:left;margin-left:0;font-size:27px;max-width:none;line-height:1.5;white-space:nowrap}
@media (max-width:640px){.hero-left .lead{font-size:20px}}
/* Free to cancel line — 130% of base muted size */
.free-cancel{font-size:21px}
/* Why ClassPixie — stacked label left, check-mark reasons right */
.why-row{display:flex;align-items:flex-start;gap:3rem;margin-top:2rem}
.why-label{display:flex;flex-direction:column;font-size:32px;font-weight:500;letter-spacing:.08em;line-height:1.1}
.why-reasons{display:flex;flex-direction:column;gap:1.2rem;padding-top:.3rem}
.why-item{display:flex;align-items:flex-start;gap:.8rem;color:#888;letter-spacing:.02em}
.why-item strong{display:block;font-size:24px;font-weight:500;color:#ccc}
.why-item p{margin:.2rem 0 0;font-size:18px;line-height:1.5;color:#888}
.why-check{font-size:24px;color:#888;flex-shrink:0;margin-top:.1rem}
@media (max-width:640px){.why-row{flex-direction:column;gap:1rem}.why-label{font-size:24px}.why-item strong{font-size:18px}.why-item p{font-size:15px}}
/* Hero right: studio picker — white box bleeding into the right edge. */
.hero-right{flex:0 0 25%;align-self:center;margin-right:-4rem;display:flex}
@media (max-width:800px){.hero-right{flex:none;width:auto;margin-right:-4rem;margin-left:0}}
@media (max-width:640px){.hero-right{margin-right:-1.5rem}}
.studio-box{background:#fff;border-radius:0;padding:2.4rem 2.2rem;display:flex;flex-direction:column;gap:1rem;flex:1;justify-content:center}
.studio-box-h{font-size:22px;font-weight:500;color:#000;margin:0 0 .6rem;text-align:left;letter-spacing:.01em}
.studio-box .provtile{min-height:auto;padding:2.2rem 1.4rem;margin:0;border-radius:.4rem;background:#111;border-color:#222}
.studio-box .provtile:hover{background:#1a1a1a}
.studio-box .provsub{color:#999}
.box-cta{margin-top:auto;padding-top:1.2rem;text-align:right}
.box-signup{font-size:17px;font-weight:500;color:#000;border:2px solid #000;background:none;text-decoration:none;display:inline-block;padding:.7rem 1.6rem;letter-spacing:.05em}
.box-signup:hover{background:#000;color:#fff}
.box-signin{display:block;margin-top:.5rem;font-size:13px;color:#222;text-align:right}
.box-signin a{color:#000;text-decoration:underline;border-bottom:none}
.box-signin a:hover{color:#444}
/* Hero heading */
.landing-hero{font-family:var(--font-heading);font-weight:400;font-size:11vw;line-height:1;letter-spacing:-.04em;margin:0 0 8rem;text-align:left;white-space:nowrap}
@media (max-width:1000px){.landing-hero{font-size:9.5vw}}
@media (max-width:640px){.landing-hero{font-size:14vw;white-space:normal;margin-bottom:3rem}}
.pop{color:#7C5CFF}
/* Not your studio yet */
.studio-req-h{font-size:20px;font-weight:500;color:#fff;margin:0 0 .5rem}
.studio-req-form{display:flex;gap:.8rem;align-items:stretch;margin:.8rem 0 0}
.studio-req-form input{flex:1;border:1px solid #2c2c2c;border-bottom:1px solid #2c2c2c;border-radius:.5rem;padding:.8rem .9rem;background:#141416;font-family:var(--font-body);font-size:17px}
.studio-req-form input:focus{border-color:#7C5CFF}
.studio-req-form button{width:auto;margin:0;padding:.8rem 1.3rem;border-radius:.5rem;font-size:17px}
