/* ================= BROVO design system =================
   One set of decisions that every screen is built from. Loaded last, so it wins over older rules.
   Type roles   caption 11 caps · label 13 · body 15 · heading 17 · title 32 serif · display 38 serif · numbers 24 / 64 / 99
   Shapes       card 24 (containers) · control 18 (rows, inputs, rating) · pill · circle
   Heights      hero 70 (the one thing to do) · control 44 (everything you tap) · chip 36 (choices inside a row)
   Buttons      primary (orange) · secondary (soft) · quiet (text) · danger (red text, asks twice)
   Colour       lime = today / now / live · orange = the primary action · cream = a selected choice · green/yellow/orange dots = effort only */
:root { --r-card: 24px; --r-ctl: 18px; --h-hero: 4.4rem; --h-ctl: 2.75rem; --h-chip: 2.25rem; }

/* ---- type roles ---- */
.eyebrow, .dstat, label.field, .step output, .ratehd, .wt small, .stat span, .swipe .swl small { font: 800 .6875rem/1.25 var(--sans); letter-spacing: .13em; text-transform: uppercase; }
.nm small, .hint, .muted, .stxt span, .about .ver, .start .t small, .toast { font-size: .8125rem; font-weight: 600; letter-spacing: 0; text-transform: none; }
.nm b, .stxt b, .card b, .srow b, .acct b, .hist-name { font: 700 1.0625rem/1.25 var(--sans); }
.htitle, .lifttitle { font: 400 2.4rem/1.02 var(--serif); letter-spacing: -.012em; }
.top h1, .top h2, .sheet .sheethd h2, .sheet.tall .sheethd h2 { font: 400 2rem/1.1 var(--serif); letter-spacing: -.01em; }
.stat b, .wt b { font: 800 1.5rem/1.05 var(--sans); letter-spacing: -.02em; }
.hero b { font: 800 4rem/1 var(--sans); letter-spacing: -.03em; }

/* ---- shapes ---- */
.lifts, .numcard, .hero, .card, .stat, .chart, .about, .settings .acct, .settings .about { border-radius: var(--r-card); }
.stage[data-mode="work"] > .listwrap { border-radius: var(--r-card) var(--r-card) 0 0; }
.sheet { border-radius: var(--r-card) var(--r-card) 0 0; }
input[type="text"], input[type="email"], input:not([type]) { border-radius: var(--r-ctl); min-height: var(--h-ctl); }
.rpe.rate button, .rpe button { border-radius: var(--r-ctl); }

/* ---- buttons ---- */
/* primary, hero size: the one thing to do on a screen */
.cta, .start, .start.done { min-height: var(--h-hero); border-radius: 999px; }
.cta, .row2 .cta { font: 800 .9375rem/1 var(--sans); letter-spacing: .1em; text-transform: uppercase; padding: 0 1.5rem; }
.start .t, .start.done .t { font: 800 1rem/1.1 var(--sans); letter-spacing: .1em; }
.swipe { height: var(--h-hero); }
/* primary, control size (inside a card) */
.btn:not(.ghost), .pill.accent { min-height: var(--h-ctl); border-radius: 999px; font: 800 .8125rem/1 var(--sans); letter-spacing: .08em; text-transform: uppercase; }
/* secondary: soft, no outline */
.cta.ghost, .row2 .cta.ghost, .btn.ghost, .pill, .pill.soft, .minibtn, .restrow button, .about .pill, .tools .pill, .tools:not(.quiet) .pill {
  min-height: var(--h-ctl); border-radius: 999px; font: 700 .8125rem/1 var(--sans); letter-spacing: 0; text-transform: none; background: var(--surface); color: var(--fg); border: 0; box-shadow: none; padding: 0 1.15rem; }
.pill.accent, .btn:not(.ghost) { background: var(--accent); color: var(--on-accent); }
.pill, .minibtn, .restrow button { display: inline-flex; align-items: center; justify-content: center; gap: var(--s2); }
.about .pill { box-shadow: inset 0 0 0 1px var(--line); background: transparent; }
.restrow button { height: var(--h-ctl); }
.cta.ghost:active, .pill:active, .minibtn:active, .restrow button:active { background: var(--surface-2); }
/* quiet: text only, never underlined */
.link, .tools.quiet .link { min-height: var(--h-ctl); text-decoration: none; color: var(--muted); font: 600 .8125rem/1 var(--sans); padding: 0 .6rem; }
.link:active { color: var(--fg); }
/* danger: red text, and it always asks twice (the label changes on the first tap) */
.link.danger, .pill.danger { color: #f29a84; background: transparent; }
:root[data-theme="light"] .link.danger, :root[data-theme="light"] .pill.danger { color: var(--accent); }
.minibtn.sure, .endbtn.sure { background: var(--accent); color: var(--on-accent); }
/* chips: choices inside a row */
.seg button, .seg.sm button, .seg.days button, .sctl .seg button { min-height: var(--h-chip); font: 700 .8125rem/1 var(--sans); padding: 0 .85rem; }
.seg.days button { font-weight: 600; }
.endbtn, .stage[data-mode="work"] .endbtn { min-height: var(--h-chip); padding: 0 .9rem; background: var(--surface); border: 0; color: var(--muted); }

/* ---- rating: plain until pressed ---- */
.rpe.rate button, .rpe.rate button[data-v] { min-height: var(--h-hero); background: var(--surface); box-shadow: none; border: 0; font: 800 1rem/1 var(--sans); }
.rpe.rate button[data-v="easy"]:active, .rpe.rate button[data-v="easy"].popped { background: color-mix(in srgb, var(--hi) 30%, var(--surface)); box-shadow: inset 0 0 0 1.5px var(--hi); }
.rpe.rate button[data-v="good"]:active, .rpe.rate button[data-v="good"].popped { background: color-mix(in srgb, var(--good) 30%, var(--surface)); box-shadow: inset 0 0 0 1.5px var(--good); }
.rpe.rate button[data-v="hard"]:active, .rpe.rate button[data-v="hard"].popped { background: color-mix(in srgb, var(--accent) 32%, var(--surface)); box-shadow: inset 0 0 0 1.5px var(--accent); }

/* ---- one stepper: a pill with two round buttons. Large in the workout, compact in the editor ---- */
.step { background: var(--surface); border: 0; border-radius: 999px; padding: 4px; }
.step button { width: 3.4rem; height: 3.4rem; border-radius: 50%; background: var(--surface-2); font-size: 1.5rem; }
.mini { background: var(--surface); border-radius: 999px; padding: 3px; min-height: var(--h-ctl); }
.mini button { width: 2.25rem; height: 2.25rem; border-radius: 50%; background: var(--surface-2); font-size: 1.1rem; }
.mini output { flex: 1; font: 700 .8125rem/1 var(--sans); }

/* ---- one switch ---- */
.switch[aria-checked="true"] { background: var(--good); }
.switch[aria-checked="true"] i { background: var(--on-hi); }
.linkbtn { color: var(--fg); }

/* ---- the lime rule: lime marks today / now / live, nothing else ---- */
.lifts li.liftrow.cur .nm small { color: var(--hi); }

/* ---- the lift editor: label on the left, control on the right, like Settings ---- */
.lifts li.liftrow .editor { display: grid; gap: 0; }
.lifts li.liftrow .editor > .pills { margin-bottom: .35rem; }
.erow { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); min-height: 3.1rem; padding: .2rem 0; }
.erow + .erow { border-top: 1px solid var(--line); }
.erow .el { font: 600 .9375rem/1.25 var(--sans); color: var(--fg); }
.erow.full { flex-direction: column; align-items: stretch; gap: var(--s2); padding: .6rem 0; }
.seg.wrap { flex-wrap: wrap; border-radius: var(--r-ctl); gap: 2px; }
.seg.wrap button { flex: 1 0 auto; }
.lifts li.liftrow .editor > .link { margin-top: .3rem; }
/* leftovers from older rules */
.stage .dockbar .dstat, .stage[data-mode="work"] .endbtn, .lifts .wt small, .lifts li.liftrow.cur .nm small { font: 800 .6875rem/1.25 var(--sans); letter-spacing: .13em; text-transform: uppercase; }
.stage[data-mode="work"] .dockbar, .stage .dockbar { min-height: var(--h-ctl); }
.start, .start.done { height: var(--h-hero); padding: 0 .5rem 0 1.6rem; }
.start .go { width: 3.4rem; height: 3.4rem; }
.switch { background: color-mix(in srgb, var(--fg) 18%, transparent); }
.switch[aria-checked="true"] { background: var(--good); }

/* ---- messages: in a workout they live in the dock's status line; elsewhere just under the top bar ---- */
#toast { top: calc(env(safe-area-inset-top, 0px) + 4.9rem); bottom: auto; }
#toast.low { top: auto; bottom: calc(env(safe-area-inset-bottom, 0px) + 1.4rem); }
.dockmsg { position: absolute; z-index: 4; left: 1rem; right: 5.4rem; top: .5rem; height: var(--h-chip); display: flex; align-items: center; justify-content: center; gap: var(--s3); background: var(--bg); border-radius: 999px; font: 600 .8125rem/1 var(--sans); color: var(--fg); white-space: nowrap; overflow: hidden; }
.dockmsg span { overflow: hidden; text-overflow: ellipsis; }
.dockmsg button { background: none; border: 0; color: var(--accent); font: 800 .8125rem/1 var(--sans); padding: 0 .2rem; cursor: pointer; min-height: var(--h-chip); }

/* ---- the number card takes the room that is left, so there is no dead gap ---- */
.stage[data-mode="work"] .upper.gym, .stage.previewing .upper.gym { flex: 1; }
.stage[data-mode="work"] .upper.gym .numcard, .stage.previewing .upper.gym .numcard { flex: 1 1 auto; margin-block: .6rem 0; align-content: center; min-height: clamp(8.5rem, 17.5dvh, 13.4rem); }
.stage[data-mode="work"] .numcard .big { font-size: clamp(5rem, 12.5dvh, 7rem); }

/* ---- sheets: history, Settings data group, streak caption ---- */
.slist.data { border-top: 1px solid var(--line); margin-top: .4rem; }
.slist.data .srow:first-child { border-top: 0; }
.slist.danger-zone { margin-top: 1rem; }
.backlink { justify-self: start; padding-left: 0; font-size: .9375rem; }
.lifts li.liftrow.editing { background: var(--surface-2); }
.lifts li.liftrow.editing .editor { padding: .4rem 1rem 1rem; }
.row2.editactions { align-items: center; margin-top: .5rem; }
.hero .eyebrow { margin-top: .1rem; }
.hero .dots { margin-top: .2rem; }
/* the workout summary keeps its one primary action in reach */
.screen:has(.stats) .lower { position: sticky; bottom: 0; padding-bottom: calc(.4rem + env(safe-area-inset-bottom, 0px)); background: linear-gradient(to bottom, transparent, var(--bg) 22%); z-index: 2; }

/* ---- light theme and small corrections from the phone ---- */
:root[data-theme="light"] .stage[data-mode="work"] > .listwrap { box-shadow: 0 -12px 28px -20px rgba(60, 30, 10, .35), inset 0 1px 0 var(--line); }
:root[data-theme="light"] .lifts li.liftrow.cur .nm small { color: #7a7410; }
.skipmark { display: block; width: 14px; height: 2px; border-radius: 2px; background: var(--muted); }
.seg[aria-label="Lift"] { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent); }

/* the top glow and grain fade in from nothing, so there is no hard edge where the status bar ends */
.app::before { -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 3.2rem); mask-image: linear-gradient(to bottom, transparent 0, #000 3.2rem); }
.app::after { -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 2.2rem, transparent 46%); mask-image: linear-gradient(to bottom, transparent 0, #000 2.2rem, transparent 46%); }

/* ================= motion, depth and polish tokens (pass 2) ================= */
/* one set of durations and curves: press feedback is quick, state changes are calm, big moves take their time */
:root { --t-press: .12s; --t-base: .26s; --t-slow: .46s; --press: .97;
  --hl: inset 0 1px 0 rgba(255, 245, 230, .05);
  --elev-1: 0 1px 0 rgba(0, 0, 0, .25), 0 10px 24px -16px rgba(0, 0, 0, .5);
  --elev-2: 0 -16px 36px -20px rgba(0, 0, 0, .7), 0 20px 44px -18px rgba(0, 0, 0, .55); }
:root[data-theme="light"] { --hl: inset 0 1px 0 rgba(255, 255, 255, .7);
  --elev-1: 0 1px 0 rgba(60, 30, 10, .06), 0 10px 22px -16px rgba(60, 30, 10, .28);
  --elev-2: 0 -12px 28px -20px rgba(60, 30, 10, .35), 0 18px 40px -18px rgba(60, 30, 10, .3); }

/* ---- Welcome: a first impression with room to breathe ---- */
.upper.welcome { gap: var(--s5); }
.wlogo { display: grid; gap: var(--s3); padding: 2.4rem 0 1rem; }
.wordmark.xl { height: auto; font-size: 4.2rem; letter-spacing: -.05em; }
.wtag { font: 400 2.1rem/1.08 var(--serif); letter-spacing: -.01em; text-wrap: balance; }
.wtag em { font-style: italic; color: var(--accent); }
.slist.wset { background: var(--surface); border-radius: var(--r-card); padding: .25rem 1.1rem; box-shadow: var(--hl); }
.slist.wset .srow { padding: .9rem 0; }
.lower .legal { text-align: center; padding: .2rem 1rem 0; }
.lower .legal a { color: var(--muted); text-decoration: underline; text-underline-offset: 3px; }
.slist.wset .pill { background: var(--surface-2); }

/* ---- depth: two levels. Raised things get a hairline highlight; floating things (dock, sheets, messages) get a shadow ---- */
.card, .hero, .stat, .numcard, .settings .acct, .settings .about, .slist.wset { box-shadow: var(--hl); }
.lifts { box-shadow: var(--hl), var(--elev-1); }
.stage[data-mode="work"] > .listwrap, :root[data-theme="light"] .stage[data-mode="work"] > .listwrap { box-shadow: var(--elev-2), var(--hl); }
.sheet { box-shadow: var(--elev-2), var(--hl); }
#toast { box-shadow: var(--elev-1); }
.numcard.resting { box-shadow: 0 0 46px -20px var(--glow), var(--hl); }

/* ---- one press feeling for everything you can tap ---- */
.pill, .minibtn, .cta, .btn, .restrow button, .rpe button, .step button, .mini button, .seg button, .iconbtn, .link, .start, .endbtn, .dockbar {
  transition: transform var(--t-press) var(--ease), background-color var(--t-base) var(--ease), color var(--t-base) var(--ease), border-color var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease), opacity var(--t-base) var(--ease); }
.pill:active, .minibtn:active, .cta:active, .btn:active, .restrow button:active, .rpe button:active, .step button:active, .mini button:active, .seg button:active, .iconbtn:active, .start:active, .endbtn:active { transform: scale(var(--press)); }

/* ---- type polish ---- */
html { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; font-kerning: normal; }
output, .wt b, .stat b, .big, .clock, .dstat, .nm small, .hero b, .ix { font-variant-numeric: tabular-nums; }
output, .wt, .dstat { white-space: nowrap; }
.htitle, .lifttitle, .top h1, .top h2, .sheet .sheethd h2, .wtag, .quip, .hint, .card b { text-wrap: balance; }
.muted, .stxt span, .card span, .nm small { text-wrap: pretty; }
.pills .pill { max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; line-height: 2.75rem; padding-block: 0; }

/* ---- rows: breathing room on both sides, so weights never sit against the container's edge ---- */
:root { --row-x: 1.2rem; }
.lifts { padding: .3rem .15rem; }
.lifts li.liftrow .hd { padding-inline: var(--row-x); }
.lifts li.liftrow:not(:first-child) .hd::before { left: var(--row-x); right: var(--row-x); }
.lifts li.liftrow .editor { padding-inline: var(--row-x); }
.lifts li.liftrow.editing .editor { padding-inline: var(--row-x); }
.lifts li.liftrow.lifting, .lifts li.liftrow.grouped { margin-inline: -.15rem; padding-inline: 0; }
.lifts li.liftrow.swiping .hd, .lifts li.liftrow.delopen .hd { margin-inline: 0; padding-inline: var(--row-x); }
.del { right: .6rem; }
.screen { scrollbar-width: none; }
.screen::-webkit-scrollbar { display: none; }

/* the "Add a lift" row: a quiet last row, with a plus where the number would be */
.lifts li.liftrow.addrow .hd { cursor: pointer; }
.lifts li.liftrow.addrow .ix { font: 400 1.7rem/1 var(--sans); color: var(--muted); }
.lifts li.liftrow.addrow .nm b { color: var(--muted); font-weight: 600; }
.lifts li.liftrow.addrow:active .nm b, .lifts li.liftrow.addrow:active .ix { color: var(--fg); }

/* the glow and the dotted grain run all the way to the top edge of the phone, under the status bar (same setup as DUNCE) */
.app::before { -webkit-mask-image: none; mask-image: none; }
.app::after { -webkit-mask-image: linear-gradient(to bottom, #000, transparent 46%); mask-image: linear-gradient(to bottom, #000, transparent 46%); }

/* Safari (iOS 26 and later) colours its top bar from a real fixed element at the top edge, not from theme-color.
   This strip follows the theme's background live. It is 12px tall and kept just visible enough that Safari reads it. */
.bartint { position: fixed; top: 0; left: 0; right: 0; height: 12px; background-color: var(--bg); opacity: .12; pointer-events: none; z-index: 40; }
/* in a browser the page starts below the status bar, so the glow and grain fade in instead of starting with a hard edge;
   in the installed app they run to the very top, under the status bar */
@media not all and (display-mode: standalone) {
  .app::before { -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 3.2rem); mask-image: linear-gradient(to bottom, transparent 0, #000 3.2rem); }
  .app::after { -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 2.2rem, transparent 46%); mask-image: linear-gradient(to bottom, transparent 0, #000 2.2rem, transparent 46%); }
}

/* ---- pass 2: snap the last off-scale values to the system ---- */
.lifts li.liftrow, .lifts li.liftrow .hd { border-radius: var(--r-ctl); }
.lifts li.liftrow .ix, .ix { font-size: 1.0625rem; }
.swl b { font-size: 1rem; }
.settings .acct b { font-size: 1.0625rem; }
/* small round buttons keep their look but get a 44px touch area */
.mini button { font-size: 1.0625rem; }
.lifts li.liftrow .pencil { position: relative; }
.lifts li.liftrow .pencil::after { content: ""; position: absolute; inset: -7px; border-radius: 50%; }

/* ---- spacing scale: every gap is one of these ---- */
:root { --s1: .25rem; --s2: .5rem; --s3: .75rem; --s4: 1rem; --s5: 1.5rem; --s6: 2rem; }

/* ---- the lift picker ---- */
.upper.pick { gap: var(--s3); }
.upper.pick > .eyebrow { margin-top: var(--s2); }
.lifts li.liftrow .ix.addplus { font: 400 1.7rem/1 var(--sans); color: var(--muted); }
.lifts li.liftrow .wt small { max-width: 7rem; text-align: right; white-space: normal; line-height: 1.25; }
