/* ==========================================================================
   Quill QR

   Same system as the other Quill mini-apps - the tokens, the wordmark rules,
   the three control shapes are lifted unchanged from Quill Stock
   (/root/quill-stock/static/css/app.css), which in turn takes its colour and
   type from the main site at
   /root/Quill-Reference/dev/assets/css/site.css.

   Do not invent a new height, radius, padding or button style here. If a new
   screen needs something that does not exist, add it as a named token first.

   One difference from Stock: that app is installed to a home screen and pins
   its pages with position:fixed. This one is opened in a browser, mostly on a
   desktop, so the page scrolls normally.
   ========================================================================== */

@font-face {
  font-family: "Helvetica Now";
  src: url("../fonts/HelveticaNowDisplay-Regular.otf") format("opentype");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Helvetica Now";
  src: url("../fonts/HelveticaNowDisplay-Medium.otf") format("opentype");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Helvetica Now";
  src: url("../fonts/HelveticaNowDisplay-Bold.otf") format("opentype");
  font-weight: 700; font-style: normal; font-display: swap;
}

:root {
  /* ---- brand colour -------------------------------------------------- */
  --bg:          #f7f7f7;
  --ink:         #2e2e2e;
  --dim:         rgba(23,23,23,.55);
  --dimmer:      rgba(23,23,23,.35);
  --line:        rgba(23,23,23,.12);
  --line-strong: rgba(23,23,23,.2);

  --panel-dark:      #171717;
  --panel-dark-ink:  #f5f5f3;

  --surface:   #ffffff;
  --surface-2: #ececea;
  --danger:    #b3261e;
  --warn:      #8a5a12;
  --ok:        #2e7d32;

  /* ---- spacing: one scale, nothing between ---------------------------- */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 32px;

  /* ---- radius: three, plus a pill ------------------------------------ */
  --r-sm:   10px;
  --r-md:   14px;
  --r-lg:   18px;
  --r-full: 999px;

  /* ---- control heights: three, and nothing else ----------------------- */
  --h-sm: 44px;
  --h-md: 52px;
  --h-lg: 60px;

  /* ---- type ----------------------------------------------------------- */
  --t-xs:      12px;
  --t-sm:      14px;
  --t-body:    15px;
  --t-input:   17px;
  --t-title:   20px;
  --t-display: 24px;

  --ease: cubic-bezier(.23, 1, .32, 1);
  --gutter: 20px;
}

/* ==========================================================================
   reset
   ========================================================================== */

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* No focus ring anywhere, matching the rest of the suite. */
*:focus, *:focus-visible, *:focus-within { outline: none !important; }

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
  background: var(--bg);
  color: var(--ink);
  /* Helvetica Now carries no Thai glyphs, so Noto Sans Thai sits behind it. */
  font-family: "Helvetica Now", "Noto Sans Thai", -apple-system,
               BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  font-size: var(--t-input);
  -webkit-font-smoothing: antialiased;
}

/* ==========================================================================
   page
   ========================================================================== */

.page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  padding: 0 var(--gutter) calc(var(--s5) + env(safe-area-inset-bottom));
}

.page > * { max-width: 460px; width: 100%; margin-inline: auto; }

.page__head {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--s1);
  padding: calc(var(--s6) + env(safe-area-inset-top)) 0 var(--s2);
}

.page__body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--s5) 0 0;
}

.page__foot {
  flex: 0 0 auto;
  padding-top: var(--s5);
  text-align: center;
  font-size: var(--t-xs);
  color: var(--dimmer);
}

/* ==========================================================================
   brand mark
   The Quill wordmark is ALWAYS flat - never the gold bulb, never a gradient,
   on any background. The SVG is pre-flattened; the filter is belt-and-braces
   so a future file swap cannot reintroduce colour.
   ========================================================================== */

.brand { display: flex; justify-content: center; }
.brand img { height: 30px; width: auto; filter: brightness(0); }

.brand-sub {
  font-size: var(--t-xs);
  line-height: 15px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--dim);
  text-align: center;
}

/* ==========================================================================
   controls
     .btn        solid black  - THE action on this screen, one per screen
     .btn--ghost outlined     - the secondary action beside it
     .chip       outlined sm  - a secondary action anywhere else
   ========================================================================== */

.btn {
  width: 100%;
  height: var(--h-lg);
  border: 0;
  border-radius: var(--r-md);
  font-size: var(--t-input);
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  background: var(--panel-dark);
  color: var(--panel-dark-ink);
  transition: opacity .12s var(--ease);
}
.btn:disabled { opacity: .25; cursor: default; }
.btn:active:not(:disabled) { opacity: .8; }
.btn--ghost { background: var(--bg); color: var(--ink); border: 1px solid var(--line-strong); }

.chip {
  font-family: inherit;
  font-size: var(--t-sm);
  height: var(--h-sm);
  padding: 0 var(--s4);
  border-radius: var(--r-sm);
  border: 1px solid var(--line-strong);
  background: var(--bg);
  color: var(--ink);
  cursor: pointer;
}
.chip:active { background: var(--surface-2); }

.field {
  width: 100%;
  height: var(--h-lg);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  color: var(--ink);
  font-size: var(--t-input);
  font-family: inherit;
  padding: 0 var(--s4);
  outline: none;
}
.field::placeholder { color: var(--dimmer); }
.field.is-bad { border-color: var(--danger); }

.lbl {
  display: block;
  font-size: var(--t-sm);
  color: var(--dim);
  margin: 0 0 var(--s2);
}

.stack { display: grid; gap: var(--s2); }

/* ==========================================================================
   messages
   One slot under the field. Empty it is invisible but still occupies its
   height, so nothing below jumps when an error appears.
   ========================================================================== */

.msg {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s3);
  text-align: center;
  font-size: var(--t-body);
  line-height: 1.4;
  margin-top: var(--s3);
  color: var(--danger);
}
/* Nothing to say, no space taken. Holding the slot open the way the Stock app
   does is right there, where a fixed keypad below it would otherwise jump;
   here there is nothing below to protect and it just reads as a dead gap. */
.msg:empty { display: none; }
.msg--warn { color: var(--warn); }

/* ==========================================================================
   result
   ========================================================================== */

#go { margin-top: var(--s5); }

.result { display: none; }
.result.is-on { display: block; margin-top: var(--s5); }

/* The QR sits on its own white card because the page background is off-white -
   a QR needs a true white quiet zone around it or close scans get flaky. */
.qr {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s4);
  display: flex;
  justify-content: center;
}
.qr img {
  width: 100%;
  max-width: 300px;
  height: auto;
  display: block;
  /* A QR is a grid of hard squares. Smoothing it on the way down to screen
     size is what makes previews look furry. */
  image-rendering: pixelated;
}

.result__actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s2);
  margin-top: var(--s4);
}
.result__actions .btn { height: var(--h-md); font-size: var(--t-body); }

/* There is no "new code" control. Editing the link is what starts a new one,
   and a button that only clears a field it sits under is a control that has to
   be read and dismissed on every single visit to earn nothing. */

/* Working state on the primary button - a label swap, not a spinner. There is
   nothing else on the screen to keep busy. */
.is-working { pointer-events: none; opacity: .55; }
