/* Flow Ballroom student/instructor portal — champagne-on-dark, matching the
   Studio Manager GoldTheme palette and the approved mockups. */

:root {
  --bg: #1e1e2a;        /* GoldTheme.BarBackground */
  --panel: #232330;     /* GoldTheme.PanelBackground */
  --raised: #2d2d3a;    /* GoldTheme.ButtonBackground */
  --hairline: #3a3a4a;
  --gold: #d4af37;      /* GoldTheme.GoldAccent */
  --champagne: #f0cb80; /* GoldTheme.Champagne */
  --parchment: #c9bfa8; /* GoldTheme.Parchment */
  --dim: #8a8272;       /* GoldTheme.DimGold */
  --good: #7fbf6a;      /* GoldTheme.StatusGood */
  --bad: #e0583f;       /* the one red on the site - .badfield asked for this var before it existed */
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  font-family: 'Mulish', system-ui, sans-serif;
  background: radial-gradient(ellipse at 50% -10%, rgba(240, 203, 128, 0.10), rgba(30, 30, 42, 0) 60%), var(--bg);
  color: #fff;
  min-height: 100vh;
  line-height: 1.5;
}

.shell { max-width: 430px; margin: 0 auto; padding: 48px 28px 40px; display: flex; flex-direction: column; gap: 16px; }
.shell.wide { max-width: 560px; padding-top: 24px; }

.brandblock { display: flex; flex-direction: column; align-items: center; gap: 8px; margin-bottom: 24px; }
.wordmark { font-family: Georgia, 'Times New Roman', serif; font-size: 2.2rem; font-weight: 600; color: var(--champagne); letter-spacing: 0.02em; }
.wordmark.small { font-size: 1.3rem; }
/* Its own line under the wordmark, and the only red on the site. Red because every
   other colour here means something ordinary - gold is the brand, amber is "the studio
   said no" - and this must not read as either. It says which building you are standing
   in, before anyone signs in and starts changing real lessons. */
.devbanner { font-size: 0.72rem; font-weight: 700; color: #e0554a; letter-spacing: 0.34em;
  text-transform: uppercase; border: 1px solid #e0554a; border-radius: 4px; padding: 2px 10px; }
.tagline { font-size: 0.68rem; font-weight: 600; color: var(--dim); letter-spacing: 0.32em; text-transform: uppercase; }
.rule { width: 56px; height: 1px; background: #4a3f22; margin-top: 8px; }

h1 { font-family: Georgia, 'Times New Roman', serif; font-size: 1.6rem; font-weight: 600; line-height: 1.2; }
.sub { font-size: 0.9rem; color: var(--parchment); }
.fine { font-size: 0.8rem; color: var(--dim); }
.error { font-size: 0.85rem; color: #e6a03c; }
.devnote { font-size: 0.85rem; color: var(--good); background: rgba(127, 191, 106, 0.10); border: 1px dashed rgba(127, 191, 106, 0.4); border-radius: 8px; padding: 8px 12px; }

.stack { display: flex; flex-direction: column; gap: 12px; }
.stack label { font-size: 0.72rem; font-weight: 700; color: var(--parchment); letter-spacing: 0.08em; text-transform: uppercase; }
.stack input[type="tel"], .stack input[type="text"] {
  height: 52px; background: var(--raised); border: 1px solid #4a3f22; border-radius: 10px;
  padding: 0 16px; font: inherit; font-size: 1.05rem; color: #fff; outline: none;
}
.stack input::placeholder { color: var(--dim); }
.stack input:focus { border-color: var(--gold); }

button {
  height: 50px; background: var(--gold); color: var(--bg); border: none; border-radius: 10px;
  font: inherit; font-size: 1rem; font-weight: 700; cursor: pointer;
}
button:hover { background: #c6a028; }
button.ghost { background: transparent; color: var(--parchment); border: 1px solid var(--hairline); font-weight: 600; }
button.ghost:hover { background: var(--raised); }

a { color: var(--champagne); text-decoration: none; }
a:hover { color: var(--gold); }

/* THE OTHER DOOR, below the sign-in rather than above it. Set apart by a rule and a little air
   so it reads as an alternative for whoever needs it, not as the next step for everybody - which
   is what it looked like while it sat above the form. */
.otherdoor { border-top: 1px solid var(--raised); margin-top: 22px; padding-top: 18px; }
.otherdoor .fine { margin-top: 8px; }
/* THE JUMP LIST. Grouped, dense, and screen-only - the print rule above hides .qrhide. Two columns
   where there is room so a dozen classes do not push the first code off the screen, one on a phone.
   The count beside each heading is there because "Classes 11" answers the question somebody opened
   this page with more often than any single link does. */
.qrjump { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px 22px;
          border: 1px solid var(--raised); border-radius: 8px; padding: 14px 16px; margin: 4px 0 18px; }
.qrjumphead { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em;
              color: var(--dim); margin-bottom: 6px; }
.qrjumpn { font-weight: 600; opacity: 0.75; }
.qrjumpgroup a { display: block; font-size: 0.82rem; line-height: 1.5; padding: 2px 0;
                 text-decoration: none; }
.qrjumpgroup a:hover, .qrjumpgroup a:focus-visible { text-decoration: underline; }
.qrjumpnote { color: var(--dim); font-size: 0.72rem; }
/* The card a link lands on says so for a moment, because a jump that moves the page with no
   acknowledgement leaves somebody checking whether it did anything. */
.qrcard:target { outline: 2px solid var(--gold); outline-offset: 3px; }
/* The package sheet's own heading and its one empty state. A card with no code still occupies a
   cell, so the message sits where the square would be rather than collapsing the grid. */
.qrh2 { font-size: 1rem; font-weight: 700; margin: 30px 0 4px; letter-spacing: 0.02em; }
.qrmissing { font-size: 0.72rem; line-height: 1.5; color: var(--dim); border: 1px dashed var(--raised);
             border-radius: 6px; padding: 14px; min-height: 96px; display: flex; align-items: center; }
/* THE BUILD STAMP. Last thing on the page, dim enough to ignore and legible enough to read out
   over the phone. Not hidden when printing: a printed code sheet somebody is holding up in a studio
   is exactly the artefact where knowing which copy produced it is worth a line. */
.buildline { text-align: center; font-size: 0.65rem; letter-spacing: 0.04em; color: var(--dim);
             opacity: 0.65; padding: 14px 16px 20px; }
/* THE WAY BACK TO THE STUDIO'S OWN SITE, directly above the build line. Dimmer than a control and
   brighter than the build: it is a door somebody might want, not a thing they came here to press.
   The arrow inherits the text colour, like the two on the instructor's week. */
.backline { text-align: center; padding: 18px 16px 0; }
.backline a { display: inline-flex; align-items: center; gap: 6px; font-size: 0.75rem;
              color: var(--dim); text-decoration: none; }
.backline a:hover, .backline a:focus-visible { color: var(--gold); }
/* A settings field the site refused, and the on/off row. The refused one keeps what was typed so
   it can be corrected rather than retyped, and says so beside itself. */
.badfield { border-color: var(--bad, #b3261e) !important; }
.onoff { display: flex; align-items: center; gap: 8px; font-size: 0.86rem; }
.onoff input { width: auto; }
/* ONE EVENT ON ONE SHEET, for pinning up. Centred, generous, and the studio's own notes kept as
   they were typed - pre-wrap would honour their blank lines but also their stray trailing spaces,
   so the line breaks are drawn as <br> and the rest left to normal wrapping. */
.qrone-sheet { max-width: 520px; margin: 0 auto; text-align: center; padding: 8px 0 24px; }
.qrone-sheet svg { max-width: 300px; height: auto; }
.qr1name { font-size: 1.3rem; font-weight: 700; line-height: 1.25; margin: 14px 0 4px; }
.qr1when { font-size: 0.95rem; color: var(--dim); margin-bottom: 14px; }
.qr1facts { list-style: none; padding: 0; margin: 0 0 16px; font-size: 0.9rem; line-height: 1.8; }
.qr1notes { text-align: left; font-size: 0.86rem; line-height: 1.65; border-top: 1px solid var(--raised);
            padding-top: 14px; margin-top: 4px; }
/* A LINE OF THEIRS IN CAPITALS IS A HEADING. The studio writes "PRIVATE LESSONS" and "NO PARTNER?
   NO PROBLEM!" as titles over the paragraphs beneath them - 21 such lines across the twelve
   packages. In body weight they read as shouting; this is the whole of the difference. The letters
   are theirs either way: sm_notes_is_heading() decides weight, never words. */
.qr1head { display: inline-block; font-weight: 700; letter-spacing: 0.02em; padding-top: 6px; }
/* The studio's own code for a package, for matching a flyer on a wall to a row in the app. Printed,
   because that is where somebody reads it, and small because a student has no use for it. */
.qr1sku { font-size: 0.62rem; letter-spacing: 0.08em; color: var(--dim); margin-top: 4px; }
/* WHEN THE SHEET WAS TAKEN. Printed, not screen-only: on a wall it is the difference between
   "this is current" and "this is from March", which is the one thing paper can say about itself. */
.qrtaken { font-size: 0.6rem; letter-spacing: 0.06em; color: var(--dim); margin-top: 10px;
           opacity: 0.8; }
/* The link from a card on the full sheet to that event's or package's own page. Screen only. */
.qrone { display: inline-block; font-size: 0.7rem; margin-top: 8px; }
@media print {
  /* A printed single sheet is the whole page: no grid, no gutters, and the code big enough to scan
     from across a room. */
  .qrone-sheet { max-width: none; }
  .qrone-sheet svg { max-width: 360px; }
}
@media print { .qrh2 { break-before: page; } }
.footer { border-top: 1px solid var(--raised); padding-top: 18px; margin-top: 24px; text-align: center; font-size: 0.75rem; color: var(--dim); }
/* The ack page's footer is the only one carrying LINKS - the one quiet way into the portal
   from a flow that deliberately does not end there. Dim like the rest of the footer, so it
   reads as a way out rather than as the point of the page. */
.footer a { color: var(--dim); text-decoration: underline; }
.footer a:hover, .footer a:focus-visible { color: var(--ink); }

/* Signed-in top bar */
.appbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 20px; border-bottom: 1px solid var(--raised); background: var(--bg);
}
.appbar-right { display: flex; align-items: center; gap: 14px; }
.who { font-size: 0.85rem; color: var(--parchment); }
.signout { font-size: 0.85rem; color: var(--dim); padding: 10px; margin: -10px; }

/* Heartbeat */
.live { display: flex; align-items: center; gap: 7px; font-size: 0.78rem; color: var(--dim); }
.live .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--good); }
.stale { font-size: 0.8rem; color: var(--parchment); background: var(--panel); border: 1px solid var(--hairline); border-radius: 10px; padding: 10px 14px; }

/* Booking picker */
.shell.haslessonbar { padding-bottom: 220px; }
.pickgroup { display: flex; flex-direction: column; gap: 8px; }
.pickhead { display: flex; align-items: center; justify-content: space-between; }
.picklabel { font-size: 0.72rem; font-weight: 700; color: var(--parchment); letter-spacing: 0.08em; text-transform: uppercase; }
.legend { display: flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--dim); }
.lg { width: 8px; height: 8px; border-radius: 3px; display: inline-block; }
.lg.open { background: var(--raised); border: 1px solid var(--hairline); }
.lg.taken { background: #191922; border: 1px solid #262630; }
.chiprow { display: flex; gap: 8px; flex-wrap: wrap; }
.chip { display: flex; align-items: center; justify-content: center; min-height: 44px; padding: 8px 18px;
        background: var(--panel); border: 1px solid var(--hairline); border-radius: 10px;
        font-size: 0.95rem; font-weight: 600; color: var(--parchment); }
.chip.sel { background: #46415a; border-color: var(--champagne); color: var(--champagne); }
.chip.day { flex-direction: column; gap: 1px; min-width: 52px; padding: 6px 10px; }
.chip.day .dow { font-size: 0.7rem; color: var(--dim); }
.chip.day .dom { font-size: 1rem; color: inherit; }
.chip.day.sel .dow { color: #6b5a2a; }
.chip.day.sel { background: var(--champagne); border-color: var(--champagne); color: var(--bg); }
.timegrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.tchip { display: flex; align-items: center; justify-content: center; min-height: 44px;
         background: var(--raised); border: 1px solid var(--hairline); border-radius: 10px;
         font-size: 0.95rem; font-weight: 600; color: #fff; }
.tchip.sel { background: var(--gold); border-color: var(--gold); color: var(--bg); font-weight: 700; }
.tchip.taken { background: #191922; border-color: #262630; color: #55524a; text-decoration: line-through; }

.requestbar { position: fixed; left: 0; right: 0; bottom: 56px; background: var(--panel);
              border-top: 1px solid var(--raised); padding: 14px 20px 16px;
              display: flex; flex-direction: column; gap: 10px; max-width: 430px; margin: 0 auto; }
.reqwhat { font-size: 1rem; font-weight: 700; color: #fff; }
.reqsub { font-size: 0.8rem; color: var(--parchment); }
.requestbar form { display: flex; }
.requestbar button { flex: 1; }

.tabbar { position: fixed; left: 0; right: 0; bottom: 0; display: flex; background: var(--panel);
          border-top: 1px solid var(--raised); max-width: 430px; margin: 0 auto; }
.tab { flex: 1; display: flex; align-items: center; justify-content: center; min-height: 54px;
       font-size: 0.8rem; font-weight: 700; color: var(--dim); }
.tab.active { color: var(--champagne); border-top: 2px solid var(--champagne); margin-top: -1px; }
body:has(.tabbar) .shell { padding-bottom: 90px; }

/* My lessons */
.flash { font-size: 0.85rem; color: var(--good); background: rgba(127, 191, 106, 0.10);
         border: 1px solid rgba(127, 191, 106, 0.35); border-radius: 10px; padding: 10px 14px; }
.card { background: var(--panel); border: 1px solid var(--raised); border-radius: 14px; padding: 16px;
        display: flex; flex-direction: column; gap: 10px; }
.cardtop { display: flex; align-items: flex-start; gap: 14px; }
.datebox { display: flex; flex-direction: column; align-items: center; width: 46px;
           background: var(--raised); border-radius: 10px; padding: 7px 0; }
.datebox .dow { font-size: 0.65rem; font-weight: 700; color: var(--dim); text-transform: uppercase; }
.datebox .dom { font-size: 1.1rem; font-weight: 700; color: #fff; }
.cardmain { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.cardtitle { font-size: 0.95rem; font-weight: 700; color: #fff; }
.cardsub { font-size: 0.78rem; color: var(--parchment); }
.pill { border-radius: 999px; padding: 4px 10px; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.03em; }
.pill.ok { background: rgba(127, 191, 106, 0.14); color: var(--good); }
.pill.wait { background: rgba(240, 203, 128, 0.14); color: var(--champagne); }
.pill.no { background: rgba(138, 130, 114, 0.18); color: var(--dim); }
.cardnote { font-size: 0.78rem; color: var(--dim); border-top: 1px solid var(--raised); padding-top: 10px; }

/* Instructor week */
.dayblock { background: var(--panel); border: 1px solid var(--raised); border-radius: 14px; overflow: hidden; }
.dayhead { font-size: 0.78rem; font-weight: 700; color: var(--champagne); letter-spacing: 0.06em; text-transform: uppercase; padding: 12px 16px; border-bottom: 1px solid var(--raised); }
/* Role chooser (role.php) — shown when one person holds more than one role. */
.rolepick { display: block; padding: 14px 16px; border: 1px solid var(--hairline);
  border-radius: 12px; background: var(--panel); text-decoration: none; }
.rolepick + .rolepick { margin-top: 10px; }
.rolepick:hover { border-color: var(--gold); }
.rolename { display: block; color: var(--gold); font-weight: 600; }
.roledesc { display: block; font-size: 0.82rem; color: var(--dim); margin-top: 3px; }
/* The flag on the Administrator door when the studio's own system has gone quiet. Inline with the
   role name, in the pill vocabulary the rest of the site already uses, and drawn for nobody else. */
/* THE STUDIO'S SIDE, ON THE ADMIN DOOR. Directly under the role's name and above its description,
   which is the order he wrote it in - "Admin / Not checked in / Studio Manager 5.1.24" - and puts
   the lamp where an eye already lands. Plainer than either line around it: the lamp is a character
   in the sentence rather than a styled element, because a pill on a card of doors reads as
   something to press. No colour rule here at all - the red or green IS the text, which is also why
   it survives being copied into a message. */
.rolestatus { display: block; font-size: 0.74rem; color: var(--dim); margin-top: 5px;
              line-height: 1.5; }
/* THE ADMIN PAGE'S TABS. A jump row stood here for an hour and he was right about it: small-text
   navigation above a large heading reads as incidental, and the page still scrolled like one long
   document. These are the size of the heading they replace - the tab IS the title now - and the
   selected one is held by a gold rule under it rather than by colour alone, which keeps it legible
   to somebody who cannot tell the two colours apart. Wraps to two rows on a phone. */
.admintabs { display: flex; flex-wrap: wrap; gap: 2px 4px; margin: 0 0 20px;
             border-bottom: 1px solid var(--hairline); }
.admintab { display: inline-block; padding: 8px 14px; font-size: 0.95rem; color: var(--dim);
            text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.admintab:hover, .admintab:focus-visible { color: var(--parchment); }
.admintab.sel { color: var(--gold); border-bottom-color: var(--gold); }
/* The count rides inside its tab, dimmer than the word: it is how much, not what. */
.admintabn { font-size: 0.78rem; font-weight: 700; opacity: 0.8; }
/* A one-button form sitting inline beside a link - the Clear next to the Download on the admin
   tab. A link cannot delete anything here (a browser may follow one by itself), so the control is
   a POST with a token, and this is what makes a form look like the pill beside it. */
.inlineform { display: inline; }
.inlineform button { display: inline-block; width: auto; height: auto; border: 0;
                     font: inherit; cursor: pointer; }

/* Presence flags on the studio page. A credential is never shown, only whether it is
   there, so these two states are the entire vocabulary. */
.flag { font-size: 0.72rem; letter-spacing: 0.04em; text-transform: uppercase;
  padding: 1px 7px; border-radius: 999px; border: 1px solid; }
.flag.on  { color: var(--good); border-color: rgba(127, 191, 106, 0.5); }
.flag.off { color: var(--dim);  border-color: var(--hairline); }

/* A per-card action (cancelling a lesson). Quiet by default: it sits under a booking
   the student already has, and should not compete with the booking itself. */
.cardaction { margin-top: 10px; }
.cardaction .small { height: 34px; font-size: 0.82rem; padding: 0 14px; width: auto; }

/* The confirmation an instructor has to read before a student's lesson is spent.
   Deliberately not a modal: this site has no JavaScript, and a page you scroll to and
   read is harder to dismiss with a thumb than a dialog is. */
.confirmbox { border: 1px solid var(--gold); border-radius: 12px; background: var(--panel);
  padding: 16px 18px; margin: 14px 0 18px; }
.confirmhead { color: var(--gold); font-weight: 700; font-size: 1.05rem; }
.confirmwhat { margin-top: 6px; font-size: 0.95rem; }
.confirmwhy { margin: 10px 0 14px; font-size: 0.85rem; color: var(--dim); line-height: 1.5; }
.confirmrow button { width: 100%; }
.confirmback { display: inline-block; margin-top: 10px; font-size: 0.85rem; color: var(--dim); }

/* A block the studio has not yet folded into a schedule push - still being decided, or
   refused because a student has a lesson underneath it. */
.blocknote { border: 1px solid var(--raised); border-left: 3px solid var(--gold); border-radius: 10px;
  background: var(--panel); padding: 10px 14px; margin: 10px 0; font-size: 0.88rem; color: var(--parchment); }
.blocknote.declined { border-left-color: #e6a03c; }

/* The way through to the block form. Quiet: it is used a few times a month, and the
   schedule underneath is what an instructor came to read. */
.weekaction { margin: 12px 0 4px; }
.ghostlink { color: var(--champagne); font-size: 0.88rem; text-decoration: none; }
.ghostlink:hover { text-decoration: underline; }

/* The block form. Stacked labels and native selects - a phone renders those as its own
   wheel, which beats anything this site could draw without JavaScript. */
.blockform { display: flex; flex-direction: column; gap: 6px; margin-top: 14px; }
.blockform label { font-size: 0.78rem; font-weight: 700; color: var(--champagne);
  letter-spacing: 0.06em; text-transform: uppercase; margin-top: 8px; }
.blockform select { width: 100%; height: 46px; padding: 0 12px; font-size: 1rem;
  color: var(--parchment); background: var(--raised); border: 1px solid var(--raised);
  border-radius: 10px; }
.blockform button { margin-top: 18px; }

/* The wordmark doubles as the way back to whichever view you are in. It deliberately
   does not look like a link: the chrome has none, and the affordance is that it is the
   title, which people already reach for. Hover and keyboard focus say it is live. */
/* Where you are, and the way back. It replaces the wordmark in the bar, so the first
   crumb carries the brand's weight and the rest step down from it - a trail that shouted
   as loudly as the studio's name would compete with the page it is describing. */
.crumbs { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.crumb { font-family: Georgia, 'Times New Roman', serif; font-size: 1.05rem;
  color: var(--dim); text-decoration: none; white-space: nowrap; }
.crumbs .crumb:first-child { font-size: 1.3rem; color: var(--champagne); }
a.crumb:hover { color: var(--gold); }
a.crumb:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: 4px; }
.crumb.here { color: var(--parchment); overflow: hidden; text-overflow: ellipsis; }
.crumbsep { color: var(--dim); font-size: 0.9rem; }
/* On a phone the trail must not push the name and Sign out off the bar. */
@media (max-width: 420px) {
  .crumbs .crumb:first-child { font-size: 1.1rem; }
  .crumb { font-size: 0.92rem; }
}

/* The activity log on the admin page. A list rather than a table: it is read on a phone
   at the desk, and four columns of small text is what a table would become. */
.auditlog { border: 1px solid var(--raised); border-radius: 14px; background: var(--panel);
  overflow: hidden; margin-top: 4px; }
.auditrow { display: flex; align-items: baseline; gap: 10px; padding: 9px 14px;
  border-bottom: 1px solid rgba(58, 58, 74, 0.5); font-size: 0.82rem; }
.auditrow:last-child { border-bottom: none; }
.auditwhen { width: 104px; flex: none; color: var(--dim); }
.auditwhat { flex: 1; color: var(--parchment); }
.auditwho { color: var(--champagne); }
.auditip { width: 112px; flex: none; text-align: right; color: var(--dim);
  font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; }
/* Turned away. Amber, not red: being refused is the system working, and a wall of red
   would make a studio owner think something is broken when nothing is. */
.auditrow.refused .auditwhat { color: #e6a03c; }

/* Which slice of the log you are looking at. Two choices, because a third would be a
   menu and this is a page you glance at. */
.filterrow { display: flex; gap: 8px; margin: 10px 0 8px; }
.filter { font-size: 0.78rem; color: var(--dim); text-decoration: none; padding: 4px 12px;
  border: 1px solid var(--raised); border-radius: 999px; }
.filter:hover { color: var(--champagne); }
.filter.sel { color: var(--bg); background: var(--champagne); border-color: var(--champagne); }
/* A day's worth of events, so the times below it need no date repeated on every line. */
.auditday { padding: 8px 14px 4px; font-size: 0.7rem; font-weight: 700; color: var(--champagne);
  letter-spacing: 0.08em; text-transform: uppercase; background: var(--raised); }

/* Running low. Gold rather than amber: this is an offer, not a warning - the studio is
   selling something, and a student at 1 lesson has done nothing wrong. */
/* THE SCAN LANDING on the sign-in page: the class somebody scanned, and the other door.
   Built from .topup rather than beside it because they are the same object - a bordered panel
   with a title, a sentence and one gold control - and a second set of values would drift. */
.scanbox { border: 1px solid var(--gold); border-radius: 12px; background: var(--panel);
  padding: 14px 16px; margin: 0 0 18px; }
.scanwhen { color: var(--dim); font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.04em; }
.scanname { color: var(--gold); font-weight: 700; font-size: 1.05rem; margin: 2px 0 0; }
.scanwhy { margin: 8px 0 12px; font-size: 0.88rem; color: var(--parchment); line-height: 1.5; }
.scanbuy { display: inline-block; height: 38px; line-height: 38px; padding: 0 18px;
  border-radius: 10px; background: var(--gold); color: #1a1a22; font-weight: 700;
  font-size: 0.88rem; text-decoration: none; }
.scanbuy:hover { background: var(--champagne); color: #1a1a22; }

/* CODES TO PRINT. The card is panel-dark like everything else, but the code itself keeps the
   white background Sm\Qr draws into it: a QR inverted - light modules on dark - is not read by
   most phone cameras, and this one is meant to be photographed and printed. */
.qrgrid { display: grid; gap: 18px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.qrcard { border: 1px solid var(--hairline); border-radius: 10px; padding: 12px;
  background: var(--panel); }
.qrcard svg { width: 100%; height: auto; display: block; border-radius: 6px; }
.qrname { color: var(--gold); font-weight: 700; margin: 10px 0 2px; }
.qrwhen { color: var(--parchment); font-size: 0.88rem; }
.qrurl { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 0.7rem;
  color: var(--dim); word-break: break-all; margin-top: 8px; }
.qrnote { font-size: 0.88rem; color: var(--parchment); line-height: 1.5; }
@media print {
  /* A printed sheet is the codes and their names; the page furniture is for the screen. */
  .appbar, .tabbar, .qrhide, .banner, .refreshnote { display: none !important; }
  body { background: #fff; color: #000; }
  .qrcard { break-inside: avoid; border-color: #999; background: #fff; }
  .qrname, .qrwhen, .qrurl { color: #000; }
}

.topup { border: 1px solid var(--gold); border-radius: 12px; background: var(--panel);
  padding: 14px 16px; margin: 14px 0 4px; }
.topuptitle { color: var(--gold); font-weight: 700; font-size: 1rem; }
.topupwhy { margin: 6px 0 12px; font-size: 0.88rem; color: var(--parchment); line-height: 1.5; }
.topupbuy { display: inline-block; height: 38px; line-height: 38px; padding: 0 18px;
  border-radius: 10px; background: var(--gold); color: #1a1a22; font-weight: 700;
  font-size: 0.88rem; text-decoration: none; }
.topupbuy:hover { background: var(--champagne); color: #1a1a22; }

/* Amber for a bar that is not going to do anything: today that is only "too close to book
   online". There was a matching .topup.blocked for an empty bank, and it is gone - an empty
   bank is no longer a shut door, it is something the instructor decides about when they
   answer the request (Janusz, 2026-09-26). */
.requestbar.stopped { border-top-color: #e6a03c; }

/* The one thing a student comes here to do. Full width and in the brand's gold, the
   same weight as "Text me a code" on the way in - the tab at the bottom is navigation,
   this is the invitation. */
.bookcta { display: block; height: 50px; line-height: 50px; margin: 4px 0 18px;
  border-radius: 12px; background: var(--gold); color: #1a1a22; font-weight: 700;
  font-size: 1rem; text-align: center; text-decoration: none; }
.bookcta:hover { background: var(--champagne); color: #1a1a22; }
.bookcta:focus-visible { outline: 2px solid var(--champagne); outline-offset: 3px; }

/* Students waiting on this instructor, at the top of their week. Gold, like the top-up
   offer and unlike the amber warnings: nobody has done anything wrong and nothing is
   broken - somebody is simply waiting, which is the studio working as intended. The
   panel carries no button on purpose; the instructor answers these in Studio Manager. */
.awaiting { border: 1px solid var(--gold); border-radius: 12px; background: var(--panel);
  padding: 14px 16px; margin: 14px 0 18px; }
.awaitinghead { color: var(--gold); font-weight: 700; font-size: 1rem; margin-bottom: 10px; }
.awaitingrow { display: flex; gap: 14px; align-items: baseline;
  padding: 8px 0; border-top: 1px solid var(--raised); }
.awaitingrow:first-of-type { border-top: 0; padding-top: 0; }
.awaitingwhen { flex: 0 0 8.5rem; font-size: 0.88rem; color: var(--parchment); }
.awaitingwhen strong { color: var(--champagne); font-weight: 700; }
.awaitingwho { font-size: 0.95rem; font-weight: 600; }
.awaitingfine { display: block; font-weight: 400; font-size: 0.8rem; color: var(--dim); }
.awaitingwhy { margin: 12px 0 0; font-size: 0.85rem; color: var(--parchment); line-height: 1.5; }

/* Not late - unanswered. Amber, because at this point the panel has stopped reporting
   the studio working and started reporting the studio PC not running, and the
   instructor is the person being waited on, so they are the one who should know. */
.awaiting.stuck { border-color: #e6a03c; }
.awaiting.stuck .awaitinghead { color: #e6a03c; }

/* One column on a phone: the time and the name stack rather than the name being
   squeezed into what is left of a narrow row. */
@media (max-width: 480px) {
  .awaitingrow { display: block; }
  .awaitingwhen { margin-bottom: 2px; }
}

/* A lesson the studio has cancelled. Struck through rather than explained: the pill next
   to it already reads Cancelled, so a sentence saying the time is free again was more
   words than the fact deserved. Dimmed as well as struck, because a line through
   champagne on dark is easy to miss at a glance. */
.cardtitle.struck { text-decoration: line-through; color: var(--dim); }

/* The cancel question: the question, Yes, No, and nothing else - Janusz's call, and he is
   right that a full-width gold Yes reads as the page's main action rather than as half of
   a two-way choice. `.confirmrow button` stays full width for week.php, where marking a
   lesson IS the page's main action and spends one from a student's account. */
.confirmbox.slim { padding: 14px 16px; }
.confirmact { display: flex; align-items: center; gap: 16px; margin-top: 12px; }
.confirmact form { margin: 0; }
.confirmact button { width: auto; min-width: 88px; height: 40px; font-size: 0.92rem; }
.confirmact .confirmback { margin-top: 0; }

/* Approve / turn down, on a waiting request. Approve is the expected answer and looks like it;
   turning down is the same size but quieter, because it is not the harder decision - it costs
   the student nothing and they can ask again. */
.awaitingact { display: flex; gap: 10px; align-items: center; margin-top: 8px; }
.awaitingact form { margin: 0; }
.awaitingact button { height: 36px; width: auto; min-width: 92px; font-size: 0.88rem; }

/* One reason per row, each its own form: no JavaScript here, so a select would still need a
   submit and a row of buttons reads faster on a phone than a menu plus a button. */
.reasonrow { margin: 0 0 8px; }
.reasonrow button { width: 100%; text-align: left; height: auto; padding: 10px 12px; }

/* "No lesson in the bank", on a request waiting for an instructor. Amber rather than gold: this
   one IS a caution - approving it puts a student into overdraft - and unlike the student's own
   nudge it is not an offer of anything. It never carries a number: the instructor needs the
   fact, and the figure belongs between the student and the desk. */
.awaitingempty { display: inline-block; margin-top: 4px; font-size: 0.75rem; font-weight: 700;
  color: #e6a03c; border: 1px solid #e6a03c; border-radius: 6px; padding: 1px 7px; }

/* The instructor's own day and time chips. Same shape as the student's picker - Janusz asked for
   it and it is right for a phone: two taps instead of a fortnight to scroll - but no instructor
   row, because an instructor is looking at their OWN week. */
/* The DATE carries the day's state in its background - fourteen chips have no room for words,
   which is the one place a colour genuinely earns its keep. `has` means something is on that day;
   `waiting` means something on it needs answering. Selection is restated AFTER both so it always
   wins the background: it says where you are, which outranks what is there. */
.chip.day.has     { background: var(--raised); }
.chip.day.waiting { background: var(--gold); border-color: var(--gold); color: #1a1a22; }
.chip.day.waiting .dow { color: #5a4a18; }
.chip.day.sel     { background: var(--champagne); border-color: var(--champagne); color: var(--bg); }
.chip.day.sel .dow { color: #6b5a2a; }
/* Selected AND waiting: champagne, with a gold ring so choosing another day cannot hide it. */
.chip.day.waiting.sel { box-shadow: inset 0 0 0 2px var(--gold); }

/* The day as rows, not chips. A row has room for WHO - which a chip never did and is the thing an
   instructor scans for - and for the state in a WORD, so nothing has to be decoded from a colour.
   Full-width rows are also a better tap target on a phone than a small chip. */
.daylist { display: flex; flex-direction: column; }
.dayrow { display: grid; grid-template-columns: 5.2rem 1fr auto; align-items: baseline; gap: 10px;
  padding: 11px 2px; border-top: 1px solid var(--raised); color: inherit; text-decoration: none; }
.dayrow:first-child { border-top: 0; }
.dayrow:hover { background: var(--panel); }
.dayrow.sel { background: var(--raised); }
.drtime { font-size: 0.9rem; color: var(--parchment); }
.drwho  { font-size: 0.95rem; font-weight: 600; }
.drstate { font-size: 0.75rem; font-weight: 700; color: var(--dim); text-align: right; }
.drstate.req     { color: var(--gold); }
.drstate.blocked { color: #e6a03c; }
.drstate.off     { color: var(--dim); text-decoration: line-through; }
.drstate.noshow  { color: #e6a03c; }

/* "Susan R.(3)" - the balance sits in the name itself on the instructor's pages, so there is one
   thing to read rather than two. Amber at or below zero: that is the row needing a judgement, and
   a colour here is a nudge toward a number that is already legible rather than a code replacing
   one. The student's own pages say it in a sentence instead. */
.drwho.low { color: #e6a03c; }

/* A progress check, under the name it belongs to. Its own line rather than a suffix: the roster is
   scanned down the name column, and a second line is read there while "Maria K. - Progress check"
   has to be read through. Gold because it changes how the instructor prepares, which is the one
   thing on this row worth preparing for - and it is a label, not a status, so it stays out of the
   state column where Booked and Cancelled live. */
.drpc { display: block; font-size: 0.7rem; font-weight: 600; color: var(--gold); }

/* WHAT'S ON - the studio's calendar in its agenda form. A date heading, then that day's events, so a
   student scans dates down the left and stops at one. The grid is time | name+meta | kind, with the
   middle column taking the slack: an event name is the longest thing on the row and the only one
   whose length the studio controls. */
.evday { font-size: 0.8rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--gold); margin: 22px 0 6px; }
.evday:first-of-type { margin-top: 14px; }
.evlist { display: flex; flex-direction: column; }
.evrow { display: grid; grid-template-columns: 5.2rem 1fr auto; align-items: baseline; gap: 10px;
  padding: 11px 2px; border-top: 1px solid var(--raised); }
.evrow:first-child { border-top: 0; }
.evtime { font-size: 0.9rem; color: var(--parchment); }
.evmain { min-width: 0; }
/* The name wraps rather than truncating. "FLOW BLACK COCKTAIL NIGHT" is 25 characters and an ellipsis
   on a party nobody can then identify is worse than two lines - the app's roster has to clip it into
   135px and a phone does not. */
.evname { display: block; font-size: 0.95rem; font-weight: 600; overflow-wrap: break-word; }
.evmeta { display: block; font-size: 0.78rem; color: var(--dim); margin-top: 2px; }
/* Class or party, as a quiet label rather than a status pill: it says what KIND of evening this is,
   and it is not something anybody can act on. The two colours are the only difference a glance
   needs. */
.evkind { font-size: 0.7rem; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--dim); white-space: nowrap; }
.evkind.party { color: #e6a03c; }
/* "Saturdays - 13 dates". Its own line under the duration rather than appended to it: the meta line
   is already two facts long, and this is the one that tells a student the class is a standing thing
   rather than a one-off they have to catch. */

/* "Also on at the studio" - the calendar's first three, at the foot of a student's own page. Quieter
   than anything above it on purpose: this is the studio's news on a page that belongs to the
   student's, and it earns its place by being there rather than by being loud. */

/* The instructor's way to the what's-on page. A link and nothing else: the parties themselves live
   on that page, and printing them here too would be the third surface Janusz called over-build. */
/* THE ERRANDS AT THE FOOT OF THE WEEK, as one named group rather than two loose lines each under
   its own rule. What the heading earns: everything above it is the instructor's own calendar, and
   these two are the studio's offering - which is the only thing they share. The heading matches
   .qrjumphead so the two pages agree about what a group label looks like. */
.weekgroup { margin: 18px 0 2px; padding-top: 12px; border-top: 1px solid var(--raised); }
.weekgrouphead { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em;
                 color: var(--dim); margin-bottom: 8px; }
.weekgroup a { display: flex; align-items: center; gap: 8px; font-size: 0.85rem; font-weight: 600;
               color: var(--gold); text-decoration: none; padding: 4px 0; }
/* The drawn mark before each errand. currentColor, so it is the same gold as the words and dims
   with them; sized in em so it follows the text if that ever changes. */
.lnkicon { width: 1.05em; height: 1.05em; flex: 0 0 auto; }
.weekgroup a:hover, .weekgroup a:focus-visible { text-decoration: underline; }

/* The row is no longer the link - its SECOND COLUMN is, because that is where the thing itself
   is. Underlined faintly rather than coloured: fifteen coloured names down a working day would
   read as fifteen warnings, and the amber ones have to stay the exception. */
a.drwho { color: inherit; text-decoration: none; border-bottom: 1px dotted var(--hairline); }
a.drwho:hover { color: var(--champagne); border-bottom-color: var(--champagne); }
/* An hour they work with nothing in it. Quiet on purpose: on a full day most rows are lessons and
   the free ones are the gaps between them, not the point of the page. */
.dayrow.free a.drwho { color: var(--dim); font-weight: 500; }
.dayrow.free .drstate { color: var(--dim); font-weight: 400; }

/* The menu, opened under the row it belongs to. Indented to the width of the time column so it
   reads as belonging to that row rather than to the list. Stacked, one per line, and full width:
   these are the controls that spend somebody else's money, and a tidy row of small pills is how a
   thumb hits Cancel when it meant Taken. */
.pills { display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  padding: 2px 0 14px 5.2rem; }
.pills .pillrow { margin: 0; }
.pill { height: 36px; padding: 0 16px; font-size: 0.85rem; font-weight: 600; width: auto;
  color: var(--parchment); background: var(--raised); border: 1px solid var(--hairline);
  border-radius: 18px; cursor: pointer; font-family: inherit; }
.pill:hover { color: var(--champagne); border-color: var(--champagne); }
/* The expected answer, and the only one here that is a single press. */
.pill.go { color: var(--bg); background: var(--champagne); border-color: var(--champagne); }
/* The student picker, opened from Book individual lesson. A list of names rather than a select,
   because the balance has to be readable beside each one: with no bank floor any more the
   instructor is deciding whether to put somebody further into overdraft, and a phone's native
   select shows one line of a list at a time. */
.pickwho { font-size: 0.78rem; font-weight: 700; color: var(--champagne); letter-spacing: 0.06em;
  text-transform: uppercase; margin: 2px 0 2px; }
.pill.low { color: #e6a03c; border-color: #e6a03c; }
.pillback { font-size: 0.82rem; color: var(--dim); text-decoration: none; margin-top: 2px; }
.pillback:hover { color: var(--champagne); text-decoration: underline; }
/* The link that OPENS the picker is a pill too, so a menu does not look like two kinds of thing. */
a.pill { display: inline-flex; align-items: center; text-decoration: none; }

/* The student picker's own page (pick-student.php). A page rather than a popup because there is no
   JavaScript here to open one - and a page turns out to be what a growing roll needs anyway: room
   for a search box, an A-Z strip, a back button that works and a URL that survives a reload. */
.pickfind { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.pickfindlabel { font-size: 0.78rem; font-weight: 700; color: var(--champagne);
  letter-spacing: 0.06em; text-transform: uppercase; }
.pickfindrow { display: flex; gap: 8px; }
.pickfindrow input { flex: 1; min-width: 0; height: 44px; padding: 0 12px; font-size: 1rem;
  color: var(--parchment); background: var(--raised); border: 1px solid var(--hairline);
  border-radius: 10px; font-family: inherit; }
.pickfindrow button { width: auto; height: 44px; padding: 0 18px; }

/* A-Z. One tap instead of typing, which on a phone is the difference between using this and not. */
.picklettersrow { display: flex; flex-wrap: wrap; gap: 4px; margin: 12px 0 4px; }
.pickletter { min-width: 30px; padding: 5px 0; text-align: center; font-size: 0.82rem;
  font-weight: 700; color: var(--parchment); background: var(--raised);
  border: 1px solid var(--hairline); border-radius: 8px; text-decoration: none; }
.pickletter:hover { color: var(--champagne); border-color: var(--champagne); }
.pickletter.sel { background: var(--champagne); border-color: var(--champagne); color: var(--bg); }
.pickletter.clear { min-width: auto; padding: 5px 12px; font-weight: 400; color: var(--dim); }

/* The names. Full-width rows, because a name is a tap target and a student's lesson balance has to
   be readable beside it - the instructor is deciding whether to put somebody further into debt. */
.picklist { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.pickrow { margin: 0; }
.pickname { width: 100%; height: 46px; text-align: left; padding: 0 14px; font-size: 0.95rem;
  font-weight: 600; color: var(--parchment); background: var(--panel);
  border: 1px solid var(--raised); border-radius: 10px; cursor: pointer; font-family: inherit; }
.pickname:hover { color: var(--champagne); border-color: var(--champagne); }
.pickname.low { color: #e6a03c; }

/* A line that is NOT a control: something already filed, something the studio answered, or a
   place on the desk's menu this site cannot fill yet. It sits in the menu at the position the app
   has it, so the list is not quietly shorter on a phone than at the desk. */
.pilloff { font-size: 0.82rem; color: var(--dim); line-height: 1.45; }
.pilloff.declined { color: #e6a03c; }

/* The month, on the first day chip and wherever the month turns over. A fortnight crosses one,
   and "Thu 1" on its own does not say which - but putting it on all fourteen would be noise. */
.chip.day .dmon { font-size: 0.6rem; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--dim); margin-top: 1px; }
.chip.day.sel .dmon { color: #6b5a2a; }
.chip.day.waiting .dmon { color: #5a4a18; }

/* The administrator's diagnostics: three columns of fact - what was asked, what came back, what it
   means. The meaning column carries the weight, so it wraps and the other two do not. */
.diaglist { margin-top: 10px; }
.diagrow { display: grid; grid-template-columns: 1fr auto; gap: 2px 10px; padding: 7px 0;
  border-top: 1px solid var(--raised); }
.diagrow:first-child { border-top: 0; }
.diagname { font-size: 0.82rem; font-weight: 600; overflow-wrap: break-word; }
.diagval { font-size: 0.78rem; font-weight: 700; color: var(--dim); text-align: right;
  white-space: nowrap; }
.diagval.good { color: var(--gold); }
.diagval.bad  { color: #e6a03c; }
.diagnote { grid-column: 1 / -1; font-size: 0.74rem; color: var(--dim); overflow-wrap: break-word; }

/* The paste-ready snapshot. Monospace because it is a column-aligned report and proportional type
   would scramble it, and scrollable sideways rather than wrapped for the same reason - a wrapped
   table row reads as two rows. */
.snapshot { margin: 12px 0 0; padding: 10px; background: var(--panel); border: 1px solid var(--hairline);
  border-radius: 6px; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 0.66rem;
  line-height: 1.45; color: var(--parchment); overflow-x: auto; white-space: pre; }

/* The headline stats. Big number, plain label, a line of meaning under it - and a warm edge on the
   rows that want acting on, so a page of description does not hide the one line that does not. */
.statgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px;
  margin-top: 12px; }
.stat { padding: 10px; background: var(--panel); border: 1px solid var(--hairline); border-radius: 6px; }
.stat.statwarn { border-color: #e6a03c; }
.statnum { font-size: 1.5rem; font-weight: 700; color: var(--gold); line-height: 1.1; }
.stat.statwarn .statnum { color: #e6a03c; }
.statlabel { margin-top: 3px; font-size: 0.78rem; font-weight: 600; }
.statnote { margin-top: 2px; font-size: 0.7rem; color: var(--dim); }
.snapfold { margin-top: 12px; }
.snapfold > summary { cursor: pointer; font-size: 0.78rem; color: var(--dim); }

/* The five-line verdict. Plain sentences, one per row, with a quiet marker - and a warm one on the
   rows that want doing, so the eye lands on those and not on the page. */
.plainlist { margin-top: 10px; }
.plainrow { position: relative; padding: 5px 0 5px 16px; font-size: 0.86rem; line-height: 1.45; }
.plainrow::before { content: ''; position: absolute; left: 2px; top: 12px; width: 6px; height: 6px;
  border-radius: 50%; background: var(--gold); opacity: 0.55; }
.plainrow.plainwarn { color: #f0c074; }
.plainrow.plainwarn::before { background: #e6a03c; opacity: 1; }
.plainrow strong { color: var(--gold); font-weight: 700; }
.plainrow.plainwarn strong { color: #e6a03c; }

/* "What to ask it" - questions in the reader's own words. Quoted lines sit in a column so the eye
   can run down them and pick one, with group labels small and unemphatic: the questions are the
   content, the grouping is only furniture. */
.asklist { margin-top: 10px; }
.askgroup { margin: 12px 0 4px; font-size: 0.7rem; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--dim); }
.askgroup:first-child { margin-top: 2px; }
.askq { padding: 3px 0 3px 12px; border-left: 2px solid var(--raised); font-size: 0.84rem;
  line-height: 1.5; }

/* The disclosure arrow, drawn rather than inherited. The default marker is a different glyph and a
   different size in every browser, and this one has to read as a control on a page whose whole
   argument is that it does not look busy - so it is one chevron, rotating a quarter turn on open.
   Native <details> keeps the keyboard and screen-reader behaviour that a div-and-JS version loses. */
.askfold { margin-top: 18px; }
.askfold > summary { display: flex; align-items: baseline; gap: 10px; padding: 9px 0;
  border-top: 1px solid var(--raised); cursor: pointer; font-size: 0.95rem; font-weight: 600;
  color: var(--parchment); list-style: none; }
/* Both, because WebKit still wants its own pseudo-element removed by name. */
.askfold > summary::-webkit-details-marker { display: none; }
.askfold > summary::marker { content: ''; }
.askfold > summary::before { content: ''; flex: none; width: 7px; height: 7px; margin-top: 4px;
  border-right: 2px solid var(--gold); border-bottom: 2px solid var(--gold);
  transform: rotate(-45deg); transition: transform 0.15s ease; }
.askfold[open] > summary::before { transform: rotate(45deg); }
.askfold > summary > em { font-style: normal; font-weight: 400; font-size: 0.74rem; color: var(--dim); }
.askfold > summary:hover { color: var(--gold); }

/* Joining an event, under its row. A sibling of .evrow rather than a fourth grid column: the row is
   three columns at a phone width already, and a button squeezed in beside the Class/Party pill
   would push the name into a third line. Indented to the width of the time column so it reads as
   belonging to the row above it. */
.evask { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px;
  padding: 0 2px 11px 5.2rem; }
.evask form { margin: 0; }
.evbtn { font: inherit; font-size: 0.82rem; font-weight: 600; color: var(--ink);
  background: var(--gold); border: 0; border-radius: 999px; padding: 6px 14px; cursor: pointer; }
.evbtn:hover { filter: brightness(1.08); }
/* Cancelling is not the thing the page is for, so it is quiet - outlined rather than filled. */
.evbtn.off { color: var(--dim); background: transparent; border: 1px solid var(--raised); }
.evbtn.off:hover { color: var(--parchment); border-color: var(--dim); filter: none; }
.evstate { font-size: 0.82rem; font-weight: 600; }
.evstate.ok   { color: var(--good); }
.evstate.wait { color: var(--gold); }
.evstate.no   { color: #e6a03c; }
.evfine { flex-basis: 100%; font-size: 0.72rem; color: var(--dim); }

/* The gutter is a desktop luxury. On a phone the indent costs a third of the width, so the ask
   sits under the full row instead. */
@media (max-width: 520px) {
  .evask { padding-left: 2px; }
}

/* The question. A block of its own under the row, because it is a sentence and a decision rather
   than a control strip - and the two answers sit on one line so the eye does not have to hunt for
   the way out. */
.evconfirm { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; flex-basis: 100%; }
.evask-q { flex-basis: 100%; font-size: 0.84rem; line-height: 1.5; color: var(--parchment); }
.evask-q strong { color: var(--gold); }
.evback { text-decoration: underline; }
.evback:hover { color: var(--parchment); }

