/* The Uni Deals partner portal. Built on tokens.css + site.css, light and dark.

   Operate mode, one audience: an invited merchant who wants to know what their
   discount did, whether their offer is live, and where their key is. The admin
   console's materials are inherited whole (hairline rules, tabular numerals,
   quiet uppercase labels, chips) at a calmer density, and the composition is
   its own: one ruled report object carrying the sentence the business sells,
   with the counts fused to it rather than floating beside it as tiles. */

:root {
  --pt-shell: 1120px;
  --pt-gutter: var(--tud-space-6);
  --pt-bar-h: 68px;
}

.pt-bar-row,
.pt-main,
.pt-foot-row {
  width: min(100% - (var(--pt-gutter) * 2), var(--pt-shell));
  margin-inline: auto;
}

/* ---------- Signed out ----------
   The whole viewport is the sign-in. Nothing else is reachable, so nothing
   else is drawn. */

.pt-gate-main {
  display: grid;
  min-height: 100vh;
  min-height: 100svh;
  place-content: center;
  justify-items: center;
  gap: var(--tud-space-6);
  padding: var(--tud-space-8) var(--tud-space-6);
}

.pt-gate-card {
  width: min(100%, 480px);
  padding: clamp(var(--tud-space-6), 5vw, var(--tud-space-10));
}

.pt-gate-logo { margin-bottom: var(--tud-space-6); }
.pt-gate-logo img { width: auto; height: 30px; }

.pt-gate-title { font-size: 27px; line-height: 1.15; }

.pt-gate-note {
  margin-top: var(--tud-space-3);
  max-width: 40ch;
  color: var(--tud-color-text-secondary);
  font-size: 15px;
  line-height: 1.5;
}

/* One quiet mark on the way in, and none past the door: a dashboard is a place
   of work. Floated rather than stacked, so the note closes around the shop and
   the card gains no height for carrying it. */
.pt-gate-art {
  float: right;
  width: 96px;
  margin: var(--tud-space-1) 0 var(--tud-space-2) var(--tud-space-5);
}
.pt-gate-art img { display: block; width: 100%; height: auto; }

/* The note is the only thing meant to wrap around the shop, so it contains the
   float and the form below always starts on a clean line. The 40ch cap comes
   off because the wrap already shortens the measure. */
.pt-gate-note { max-width: none; overflow: hidden; }

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .pt-gate-art { transition: transform var(--tud-duration-base) var(--tud-ease-standard); }
  .pt-gate-art:hover { transform: rotate(-4deg) scale(1.05); }
}

/* Every single-column grid on this surface states its column as minmax(0, 1fr).
   A grid's implicit column is `auto`, which sizes to its content's max-content
   width, so one unwrappable string (a widget key, a snippet line, a long store
   URL) would otherwise stretch the whole page sideways on a phone. */
.pt-gate-form,
.pt-keys,
.pt-offers,
.pt-report,
.pt-field,
.pt-offer-state,
.pt-source-legend,
.pt-grid { grid-template-columns: minmax(0, 1fr); }

.pt-key, .pt-offer, .pt-gate-card { min-width: 0; }

.pt-gate-form { display: grid; gap: var(--tud-space-5); margin-top: var(--tud-space-6); }
.pt-gate-form .field-hint { max-width: 44ch; line-height: 1.5; }
.pt-gate-form .btn { margin-top: calc(var(--tud-space-1) * -1); }

.pt-gate-sent { color: var(--tud-color-text-secondary); font-size: 15px; }
/* break-word, not break-all: an address that fits on its own line moves down
   whole instead of being split mid-domain. */
.pt-gate-sent strong { color: var(--tud-color-text-primary); overflow-wrap: break-word; }

/* A six digit code is read back character by character, so it is set like one:
   monospaced rhythm, tracked out, centred. */
.pt-code-input {
  font-family: var(--tud-font-secondary);
  font-size: 26px;
  font-weight: 700;
  letter-spacing: 0.34em;
  text-align: center;
  text-indent: 0.34em;
  font-variant-numeric: tabular-nums;
}

.pt-linkbtn {
  justify-self: center;
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  padding: 0 var(--tud-space-3);
  border: none;
  background: none;
  color: var(--site-accent-text);
  font-family: var(--tud-font-primary);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}

.pt-linkbtn:hover { text-decoration: underline; text-underline-offset: 0.18em; }

.pt-gate-foot {
  display: flex;
  align-items: center;
  gap: var(--tud-space-3);
  color: var(--tud-color-text-muted);
  font-size: 13px;
  flex-wrap: wrap;
  justify-content: center;
}

.pt-gate-foot a {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  color: var(--tud-color-text-muted);
  font-weight: 600;
}

.pt-gate-foot a:hover { color: var(--site-accent-text); }

.pt-dot { width: 3px; height: 3px; border-radius: var(--tud-radius-pill); background: var(--tud-color-border-strong); }

/* ---------- App bar ---------- */

.pt-bar {
  position: sticky;
  top: 0;
  z-index: 30;
  border-bottom: var(--tud-border-hairline) solid var(--tud-color-border-default);
  background: var(--tud-color-bg-canvas);
}

.pt-bar-row {
  display: flex;
  min-height: var(--pt-bar-h);
  align-items: center;
  gap: var(--tud-space-5);
}

.pt-brand { display: inline-flex; align-items: center; gap: var(--tud-space-3); flex: 0 0 auto; }
.pt-logo { width: auto; height: 26px; }

.pt-brand-tag {
  padding: 3px var(--tud-space-2);
  border: var(--tud-border-hairline) solid var(--tud-color-border-strong);
  border-radius: var(--tud-radius-xs);
  color: var(--tud-color-text-muted);
  font-family: var(--tud-font-secondary);
  font-size: 11px;
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.pt-bar-right { display: flex; align-items: center; gap: var(--tud-space-3); margin-left: auto; flex: 0 0 auto; }

/* Three sections, none of them a chore, so one weight for all three. The
   console's two-weight tablist would be shouting at an audience with three
   places to go. */
.pt-tabs { display: flex; align-items: center; gap: var(--tud-space-1); flex: 1 1 auto; min-width: 0; }

.pt-tab {
  position: relative;
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  padding: 0 var(--tud-space-4);
  border: none;
  border-radius: var(--tud-radius-sm);
  background: transparent;
  color: var(--tud-color-text-secondary);
  font-family: var(--tud-font-primary);
  font-size: 15px;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color var(--tud-duration-fast) var(--tud-ease-standard),
    color var(--tud-duration-fast) var(--tud-ease-standard);
}

.pt-tab:hover { color: var(--tud-color-text-primary); background: var(--tud-color-bg-sunken); }
.pt-tab.is-active { color: var(--tud-color-text-primary); }

.pt-tab.is-active::after {
  content: "";
  position: absolute;
  right: var(--tud-space-3);
  bottom: -1px;
  left: var(--tud-space-3);
  height: 2px;
  border-radius: var(--tud-radius-pill);
  background: var(--tud-color-accent-base);
}

/* ---------- Panels ---------- */

.pt-main { padding-block: var(--tud-space-8) var(--tud-space-16); }
.pt-panel:focus { outline: none; }

.pt-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--tud-space-4);
  margin-bottom: var(--tud-space-6);
  padding-bottom: var(--tud-space-4);
  border-bottom: var(--tud-border-hairline) solid var(--tud-color-border-default);
  flex-wrap: wrap;
}

.pt-head-copy { min-width: 0; }
.pt-head-tools { display: flex; align-items: center; gap: var(--tud-space-4); flex-wrap: wrap; }

.pt-brandline { display: flex; align-items: center; gap: var(--tud-space-3); min-width: 0; }

.pt-brandmark {
  display: grid;
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
  place-items: center;
  border: var(--tud-border-hairline) solid var(--tud-color-border-default);
  border-radius: var(--tud-radius-md);
  background: var(--tud-color-bg-sunken);
  color: var(--site-accent-text);
  font-family: var(--tud-font-secondary);
  font-size: 15px;
  font-weight: 700;
  overflow: hidden;
}

.pt-brandmark img { width: 76%; height: 76%; object-fit: contain; }
.pt-brandmark:empty { display: none; }

.pt-title { font-size: 27px; line-height: 1.15; }
.pt-head-sub { margin-top: var(--tud-space-2); max-width: 60ch; color: var(--tud-color-text-secondary); font-size: 15px; }
.pt-head-sub:empty { display: none; }
/* The website sits on its own line under the sentence, so it can carry a real
   tap target without breaking a paragraph. */
.pt-head-sub a { display: inline-flex; min-height: 44px; align-items: center; font-weight: 700; }

.pt-status { margin: 0; font-size: 14px; font-weight: 700; color: var(--tud-color-text-secondary); }
.pt-status:empty { display: none; }
.pt-status.is-error { color: var(--tud-color-status-error-text); }
.pt-status.is-success { color: var(--tud-color-status-success-text); }
.pt-status.is-info { color: var(--tud-color-text-muted); font-weight: 500; }

.pt-muted { color: var(--tud-color-text-muted); }

/* ---------- The report ----------
   Statement and counts are one object, not a headline card above a row of
   tiles. The 1px gaps over a border-coloured backdrop draw every rule, so the
   whole thing reads as a single ruled sheet. */

.pt-report {
  display: grid;
  gap: var(--tud-border-hairline);
  border: var(--tud-border-strong) solid var(--tud-color-border-default);
  border-radius: var(--tud-radius-xl);
  background: var(--tud-color-border-default);
  box-shadow: var(--tud-elevation-e1);
  overflow: hidden;
}

/* The sentence and where it happened share one row, divided by a single rule.
   The claim and its breakdown are one reading, not two cards. */
.pt-report-top {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: var(--tud-border-hairline);
  background: var(--tud-color-border-default);
}

.pt-split {
  display: grid;
  align-content: center;
  gap: var(--tud-space-4);
  min-width: 0;
  padding: clamp(var(--tud-space-5), 3vw, var(--tud-space-8));
  background: var(--tud-color-bg-surface);
}

.pt-split-label {
  margin: 0;
  color: var(--tud-color-text-muted);
  font-family: var(--tud-font-secondary);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.pt-split .pt-source-legend { margin-top: 0; }
.pt-split .pt-source-bar { height: 36px; }

.pt-statement {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  align-items: center;
  gap: var(--tud-space-2) clamp(var(--tud-space-6), 4vw, var(--tud-space-10));
  padding: clamp(var(--tud-space-6), 4vw, var(--tud-space-10));
  background: var(--tud-color-bg-surface);
}

/* The one place orange is spent on this view. Display-scale numerals take the
   BASE accent rather than the darkened text accent: at 56px and up this is
   large text, so #FF5C26 clears AA large at 3.08:1 on the surface, and the
   figure then matches the source bar beside it instead of reading as a second,
   muddier orange. Body-scale accent text keeps --site-accent-text. Founder
   decision, 2026-08-06. */
.pt-statement-num {
  grid-row: 1 / 3;
  margin: 0;
  color: var(--tud-color-accent-base);
  font-family: var(--tud-font-secondary);
  font-size: clamp(56px, 8.5vw, 104px);
  line-height: 0.9;
  font-weight: 700;
  letter-spacing: -0.035em;
  font-variant-numeric: tabular-nums;
}

.pt-statement-say {
  align-self: end;
  margin: 0;
  max-width: 24ch;
  font-size: clamp(19px, 2.1vw, 25px);
  line-height: 1.24;
  font-weight: 800;
  letter-spacing: -0.02em;
}

.pt-statement-sub {
  align-self: start;
  margin: 0;
  color: var(--tud-color-text-secondary);
  font-size: 15px;
  font-weight: 500;
}

.pt-statement-sub b {
  font-family: var(--tud-font-secondary);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--tud-color-text-primary);
}

/* Nothing yet is a real state with a real next step, not a zero pretending to
   be a number. */
.pt-statement--empty { grid-template-columns: minmax(0, 1fr); }
.pt-statement--empty .pt-statement-say { grid-row: auto; max-width: 34ch; align-self: auto; font-size: clamp(21px, 2.4vw, 28px); }
.pt-statement--empty .pt-statement-sub { max-width: 56ch; }
.pt-statement-do { display: flex; gap: var(--tud-space-3); margin-top: var(--tud-space-2); flex-wrap: wrap; }

.pt-strip {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--tud-border-hairline);
  background: var(--tud-color-border-default);
}

.pt-cell { min-width: 0; padding: var(--tud-space-5) clamp(var(--tud-space-5), 3vw, var(--tud-space-8)); background: var(--tud-color-bg-surface); }

.pt-num {
  margin: 0;
  color: var(--tud-color-text-primary);
  font-family: var(--tud-font-secondary);
  font-size: 30px;
  line-height: 34px;
  font-weight: 700;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}

.pt-label {
  margin: var(--tud-space-2) 0 0;
  color: var(--tud-color-text-muted);
  font-family: var(--tud-font-secondary);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.pt-cellsay { margin: var(--tud-space-1) 0 0; color: var(--tud-color-text-secondary); font-size: 12px; font-weight: 600; }

/* ---------- Cards ---------- */

/* Both remaining blocks want the full measure: thirty bars and a seven column
   table are both cramped in a third of the shell. */
.pt-grid {
  display: grid;
  align-items: start;
  gap: var(--tud-space-5);
  margin-top: var(--tud-space-5);
}

.pt-card { padding: var(--tud-space-6); }
.pt-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--tud-space-4); flex-wrap: wrap; }
.pt-card-title { margin: 0; font-size: 18px; line-height: 24px; font-weight: 700; letter-spacing: 0; }
.pt-card-note { margin-top: var(--tud-space-2); margin-bottom: var(--tud-space-4); max-width: 62ch; }

.pt-readout {
  margin: 0;
  min-height: 20px;
  color: var(--tud-color-text-secondary);
  font-family: var(--tud-font-secondary);
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ---------- Chart ----------
   Drawn here, from the numbers the endpoint sent. Two rules only: the baseline
   and the peak. No library, no gridlines nobody reads. */

.pt-chart svg { display: block; width: 100%; height: auto; }
.pt-bar { fill: var(--tud-color-accent-base); }
.pt-col:hover .pt-bar { fill: var(--tud-color-accent-pressed); }
.pt-col:hover .pt-hit { fill: var(--tud-color-bg-sunken); }
.pt-hit { fill: transparent; }
.pt-rule { stroke: var(--tud-color-border-strong); stroke-width: 1; }
.pt-rule--peak { stroke-dasharray: 3 4; }
.pt-tick { fill: var(--tud-color-text-muted); font-family: var(--tud-font-secondary); font-size: 11px; font-weight: 700; }

/* ---------- Source split ---------- */

.pt-source-bar {
  display: flex;
  height: 44px;
  border: var(--tud-border-default) solid var(--tud-color-border-default);
  border-radius: var(--tud-radius-md);
  background: var(--tud-color-bg-sunken);
  overflow: hidden;
}

.pt-source-seg { min-width: 0; }
.pt-source-seg[data-seg="app"] { background: var(--tud-color-accent-base); }
.pt-source-seg[data-seg="sdk"] { background: var(--tud-color-text-secondary); }

.pt-source-legend { display: grid; gap: var(--tud-space-3); margin-top: var(--tud-space-4); }
.pt-source-row { display: grid; grid-template-columns: 12px minmax(0, 1fr) max-content; align-items: center; gap: var(--tud-space-3); }
.pt-swatch { width: 12px; height: 12px; border-radius: var(--tud-radius-xs); }
.pt-swatch[data-seg="app"] { background: var(--tud-color-accent-base); }
.pt-swatch[data-seg="sdk"] { background: var(--tud-color-text-secondary); }
.pt-source-name { font-size: 14px; font-weight: 600; }
.pt-source-val { font-family: var(--tud-font-secondary); font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums; }
.pt-source-share { margin-left: var(--tud-space-2); color: var(--tud-color-text-muted); font-weight: 500; }

/* Honest emptiness: a framed sentence that says what would put something here. */
.pt-empty {
  display: grid;
  place-items: center;
  min-height: 132px;
  padding: var(--tud-space-5);
  border: var(--tud-border-hairline) dashed var(--tud-color-border-strong);
  border-radius: var(--tud-radius-md);
  background: var(--tud-color-bg-sunken);
  color: var(--tud-color-text-muted);
  font-size: 13px;
  font-weight: 600;
  text-align: center;
  max-width: 46ch;
  margin-inline: auto;
}

/* ---------- Tables ---------- */

.pt-table-wrap { overflow-x: auto; border: var(--tud-border-hairline) solid var(--tud-color-border-default); border-radius: var(--tud-radius-md); }
.pt-table { width: 100%; min-width: 720px; border-collapse: collapse; font-size: 14px; }
.pt-table th, .pt-table td { text-align: left; padding: var(--tud-space-3) var(--tud-space-4); border-bottom: var(--tud-border-hairline) solid var(--tud-color-border-default); }

.pt-table th {
  color: var(--tud-color-text-muted);
  background: var(--tud-color-bg-sunken);
  font-family: var(--tud-font-secondary);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
}

.pt-table th.num, .pt-table td.num { text-align: right; font-family: var(--tud-font-secondary); font-variant-numeric: tabular-nums; white-space: nowrap; }
.pt-table td.num { font-weight: 700; }
.pt-table td.pt-lead { font-weight: 700; }
.pt-table td.pt-quiet { color: var(--tud-color-text-muted); white-space: nowrap; }
.pt-table tbody tr:last-child td { border-bottom: none; }
.pt-table tbody tr.is-off td:not(.pt-status-cell) { opacity: 0.6; }
.pt-table td.pt-table-empty { padding: var(--tud-space-6) var(--tud-space-4); color: var(--tud-color-text-muted); font-weight: 500; }

/* ---------- Chips ----------
   The same formula as the console's offer chips and the public deal badges. */

.pt-chip {
  display: inline-flex;
  min-height: 24px;
  align-items: center;
  padding: 0 var(--tud-space-3);
  border: var(--tud-border-hairline) solid transparent;
  border-radius: var(--tud-radius-pill);
  font-family: var(--tud-font-secondary);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}

.pt-chip[data-tone="live"] { border-color: var(--tud-color-status-success-text); background: var(--tud-color-status-success-bg); color: var(--tud-color-status-success-text); }
.pt-chip[data-tone="wait"] { border-color: var(--tud-color-status-warning-text); background: var(--tud-color-status-warning-bg); color: var(--tud-color-status-warning-text); }
.pt-chip[data-tone="muted"] { border-color: var(--tud-color-border-strong); background: var(--tud-color-bg-canvas); color: var(--tud-color-text-muted); }
.pt-chip[data-tone="accent"] { border-color: var(--tud-color-accent-tint-border); background: var(--tud-color-accent-tint); color: var(--site-accent-text); }
.pt-chip[data-tone="late"] { border-color: var(--tud-color-status-error-text); background: var(--tud-color-status-error-bg); color: var(--tud-color-status-error-text); }

/* ---------- Offers ---------- */

.pt-offers { display: grid; gap: var(--tud-space-4); }

.pt-offer {
  border: var(--tud-border-default) solid var(--tud-color-border-default);
  border-radius: var(--tud-radius-lg);
  background: var(--tud-color-bg-surface);
  box-shadow: var(--tud-elevation-e1);
  overflow: hidden;
}

.pt-offer.is-editing { border-color: var(--tud-color-accent-base); }

.pt-offer-body { display: grid; grid-template-columns: minmax(0, 1fr) max-content; gap: var(--tud-space-3) var(--tud-space-5); padding: var(--tud-space-5); align-items: start; }

.pt-offer-meta {
  display: flex;
  align-items: center;
  gap: var(--tud-space-2);
  color: var(--tud-color-text-muted);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  flex-wrap: wrap;
}

.pt-offer-name { margin: var(--tud-space-1) 0 0; font-size: 19px; line-height: 1.2; font-weight: 800; letter-spacing: -0.01em; }
.pt-offer-discount { color: var(--site-accent-text); font-family: var(--tud-font-secondary); font-size: 14px; font-weight: 700; }
.pt-offer-say { margin: var(--tud-space-2) 0 0; max-width: 68ch; color: var(--tud-color-text-secondary); font-size: 14px; }

.pt-offer-url {
  display: inline-block;
  margin-top: var(--tud-space-2);
  max-width: 100%;
  overflow: hidden;
  color: var(--tud-color-text-muted);
  font-family: var(--tud-font-secondary);
  font-size: 12px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}

.pt-offer-state { display: grid; justify-items: end; gap: var(--tud-space-2); }

/* The one sentence a merchant staring at a paused row needs. Set as a note,
   not an alert: waiting for review is the normal path, not a fault. */
.pt-offer-review {
  grid-column: 1 / -1;
  display: flex;
  align-items: flex-start;
  gap: var(--tud-space-2);
  margin-top: var(--tud-space-1);
  padding: var(--tud-space-3) var(--tud-space-4);
  border: var(--tud-border-hairline) solid var(--tud-color-border-default);
  border-radius: var(--tud-radius-md);
  background: var(--tud-color-bg-sunken);
  color: var(--tud-color-text-secondary);
  font-size: 13px;
  font-weight: 600;
}

.pt-offer-review svg { flex: 0 0 auto; margin-top: 1px; color: var(--tud-color-text-muted); }

.pt-offer-actions {
  display: flex;
  align-items: center;
  gap: var(--tud-space-3);
  padding: var(--tud-space-3) var(--tud-space-5);
  border-top: var(--tud-border-hairline) solid var(--tud-color-border-default);
  background: var(--tud-color-bg-sunken);
  flex-wrap: wrap;
}

.pt-offer-actions .pt-status { margin-left: auto; }

/* Pause has to be pressed twice. The second press is the confirm, so a stray
   click on the way to Edit cannot take an offer down. */
.pt-pause[data-armed="true"] {
  border-color: var(--tud-color-status-error-text);
  color: var(--tud-color-status-error-text);
  background: var(--tud-color-status-error-bg);
}

/* ---------- Forms ---------- */

.pt-create {
  margin-bottom: var(--tud-space-5);
  padding: var(--tud-space-6);
  border: var(--tud-border-strong) solid var(--tud-color-accent-tint-border);
  border-radius: var(--tud-radius-lg);
  background: var(--tud-color-bg-surface);
  box-shadow: var(--tud-elevation-e2);
}

.pt-create-head { display: flex; align-items: center; justify-content: space-between; gap: var(--tud-space-4); margin-bottom: var(--tud-space-5); }

.pt-offer-edit { padding: var(--tud-space-5); border-top: var(--tud-border-hairline) solid var(--tud-color-border-default); background: var(--tud-color-bg-sunken); }
.pt-offer-edit .pt-form-foot { border-top-color: var(--tud-color-border-strong); }

.pt-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--tud-space-4); align-items: start; }
.pt-field { display: grid; gap: var(--tud-space-2); min-width: 0; }
.pt-field--wide { grid-column: 1 / -1; }

.pt-field label {
  color: var(--tud-color-text-secondary);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.pt-field input, .pt-field select, .pt-field textarea { min-height: 46px; padding: var(--tud-space-2) var(--tud-space-4); border-radius: var(--tud-radius-md); font-size: 15px; }
.pt-field textarea { min-height: 72px; resize: vertical; font-family: var(--tud-font-primary); }
.pt-field select { padding-right: 44px; }
.pt-field .field-hint { margin-top: calc(var(--tud-space-1) * -1); }

/* Native select kept, chrome matched. One control vocabulary across the
   surface matters more here than a branded popup on two fields. */
.pt-select { position: relative; display: grid; min-width: 0; }
.pt-select .select-chevron { position: absolute; top: 50%; right: var(--tud-space-4); transform: translateY(-50%); pointer-events: none; color: var(--tud-color-text-muted); }

.pt-form-foot {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: var(--tud-space-4);
  margin-top: var(--tud-space-1);
  padding-top: var(--tud-space-4);
  border-top: var(--tud-border-hairline) solid var(--tud-color-border-default);
  flex-wrap: wrap;
}

/* What happens after Save, stated before they press it. */
.pt-form-note {
  grid-column: 1 / -1;
  margin: 0;
  max-width: 64ch;
  color: var(--tud-color-text-muted);
  font-size: 13px;
  font-weight: 600;
}

/* ---------- Widget ---------- */

.pt-keys { display: grid; gap: var(--tud-space-5); margin-bottom: var(--tud-space-8); }

.pt-key {
  padding: var(--tud-space-6);
  border: var(--tud-border-default) solid var(--tud-color-border-default);
  border-radius: var(--tud-radius-lg);
  background: var(--tud-color-bg-surface);
  box-shadow: var(--tud-elevation-e1);
}

.pt-key-head { display: flex; align-items: center; justify-content: space-between; gap: var(--tud-space-4); margin-bottom: var(--tud-space-5); flex-wrap: wrap; }
.pt-key-name { margin: 0; font-size: 19px; line-height: 1.2; font-weight: 800; letter-spacing: -0.01em; }

.pt-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: var(--tud-space-3) var(--tud-space-6); margin: 0 0 var(--tud-space-5); }
.pt-facts dt { color: var(--tud-color-text-muted); font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; padding-top: 3px; }
.pt-facts dd { margin: 0; min-width: 0; font-size: 15px; font-weight: 600; }
.pt-facts dd.pt-mono { font-family: var(--tud-font-secondary); font-size: 14px; word-break: break-all; }
.pt-facts dd.pt-none { color: var(--tud-color-text-muted); font-weight: 500; }

.pt-origins { display: flex; flex-wrap: wrap; gap: var(--tud-space-2); }

.pt-origin {
  padding: 3px var(--tud-space-3);
  border: var(--tud-border-hairline) solid var(--tud-color-border-strong);
  border-radius: var(--tud-radius-sm);
  background: var(--tud-color-bg-sunken);
  font-family: var(--tud-font-secondary);
  font-size: 13px;
  font-weight: 600;
  word-break: break-all;
}

/* The block they came to copy. Same ink slab, same accent edge, same copy
   button as the snippet on theunideals.com/partners/sdk/, so the thing they
   read in the guide and the thing they paste are visibly one object. */
.pt-snippet {
  overflow: hidden;
  border-left: 4px solid var(--tud-color-accent-base);
  border-radius: var(--tud-radius-md);
  color: var(--tud-color-text-inverse);
  background: var(--tud-color-bg-inverse);
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
}

.pt-snippet + .pt-snippet { margin-top: var(--tud-space-4); }

.pt-snippet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--tud-space-4);
  padding: var(--tud-space-3) var(--tud-space-3) var(--tud-space-2) var(--tud-space-5);
}

.pt-snippet-label {
  font-family: var(--tud-font-secondary);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  line-height: 1.4;
  text-transform: uppercase;
  opacity: 0.66;
}

.pt-copy {
  display: inline-flex;
  min-height: 44px;
  flex: 0 0 auto;
  align-items: center;
  padding: 0 var(--tud-space-4);
  border: var(--tud-border-default) solid currentColor;
  border-radius: var(--tud-radius-pill);
  color: inherit;
  background: none;
  font-family: var(--tud-font-primary);
  font-size: 13px;
  font-weight: 800;
  cursor: pointer;
  transition:
    color var(--tud-duration-fast) var(--tud-ease-standard),
    border-color var(--tud-duration-fast) var(--tud-ease-standard),
    background-color var(--tud-duration-fast) var(--tud-ease-standard);
}

.pt-copy:hover {
  border-color: var(--tud-color-accent-base);
  color: var(--tud-color-ramp-neutral-950);
  background: var(--tud-color-accent-base);
}

.pt-copy:focus-visible { outline-offset: 2px; }

.pt-snippet-code {
  margin: 0;
  padding: 0 var(--tud-space-5) var(--tud-space-5);
  overflow-x: auto;
  font-size: 13px;
  line-height: 1.85;
  tab-size: 2;
}

.pt-snippet-code .pt-key-token { color: var(--tud-color-ramp-accent-300); font-weight: 700; }

.pt-key-note { margin-top: var(--tud-space-4); max-width: 68ch; }

.pt-key-note code {
  padding: 1px 5px;
  border: var(--tud-border-hairline) solid var(--tud-color-border-strong);
  border-radius: var(--tud-radius-xs);
  background: var(--tud-color-bg-sunken);
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 0.92em;
}

/* A key that is not switched on yet still gets its snippet, because the
   merchant is pasting it now and going live later. It just says so. */
.pt-key-off {
  display: flex;
  align-items: flex-start;
  gap: var(--tud-space-2);
  margin-bottom: var(--tud-space-5);
  padding: var(--tud-space-3) var(--tud-space-4);
  border: var(--tud-border-hairline) solid var(--tud-color-border-default);
  border-radius: var(--tud-radius-md);
  background: var(--tud-color-bg-sunken);
  color: var(--tud-color-text-secondary);
  font-size: 13px;
  font-weight: 600;
}

.pt-key-off svg { flex: 0 0 auto; margin-top: 1px; color: var(--tud-color-text-muted); }

.pt-guides { padding-top: var(--tud-space-6); border-top: var(--tud-border-hairline) solid var(--tud-color-border-default); }
.pt-guide-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--tud-space-4); }

.pt-guide {
  display: grid;
  grid-template-columns: minmax(0, 1fr) max-content;
  align-items: center;
  gap: var(--tud-space-1) var(--tud-space-4);
  padding: var(--tud-space-5);
  border: var(--tud-border-default) solid var(--tud-color-border-default);
  border-radius: var(--tud-radius-lg);
  background: var(--tud-color-bg-surface);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--tud-duration-fast) var(--tud-ease-standard),
              background-color var(--tud-duration-fast) var(--tud-ease-standard);
}

.pt-guide:hover { border-color: var(--tud-color-accent-tint-border); background: var(--tud-color-accent-tint); text-decoration: none; }

/* Placed explicitly, all three. Left to auto-placement the arrow takes the
   first cell and the title lands on the right, which reads as a caption. */
.pt-guide-name { grid-area: 1 / 1; font-size: 16px; font-weight: 800; }
.pt-guide-say { grid-area: 2 / 1; color: var(--tud-color-text-secondary); font-size: 14px; }
.pt-guide-arrow {
  grid-area: 1 / 2 / 3 / 3;
  align-self: center;
  color: var(--site-accent-text);
  transition: transform var(--tud-duration-fast) var(--tud-ease-standard);
}
.pt-guide:hover .pt-guide-arrow { transform: translateX(2px); }

/* ---------- Locations ----------
   The offer card's grammar, one row per branch. The poster code is set like
   the small piece of machinery it is: mono, tracked, framed. */

.pt-locs { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--tud-space-4); }

.pt-loc {
  min-width: 0;
  border: var(--tud-border-default) solid var(--tud-color-border-default);
  border-radius: var(--tud-radius-lg);
  background: var(--tud-color-bg-surface);
  box-shadow: var(--tud-elevation-e1);
  overflow: hidden;
}

.pt-loc.is-editing { border-color: var(--tud-color-accent-base); }

.pt-loc-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) max-content;
  gap: var(--tud-space-3) var(--tud-space-5);
  padding: var(--tud-space-5);
  align-items: start;
}

.pt-loc.is-off .pt-loc-info { opacity: 0.65; }

.pt-loc-meta {
  display: flex;
  align-items: center;
  gap: var(--tud-space-2);
  margin: 0;
  color: var(--tud-color-text-muted);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  flex-wrap: wrap;
}

.pt-loc-code {
  padding: 2px var(--tud-space-2);
  border: var(--tud-border-hairline) solid var(--tud-color-border-strong);
  border-radius: var(--tud-radius-xs);
  background: var(--tud-color-bg-sunken);
  color: var(--tud-color-text-secondary);
  font-family: var(--tud-font-secondary);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
}

.pt-loc-name { margin: var(--tud-space-1) 0 0; font-size: 19px; line-height: 1.2; font-weight: 800; letter-spacing: -0.01em; }

.pt-loc-nums { margin: var(--tud-space-2) 0 0; color: var(--tud-color-text-secondary); font-size: 14px; font-weight: 500; }
.pt-loc-nums b {
  color: var(--tud-color-text-primary);
  font-family: var(--tud-font-secondary);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.pt-loc-state { display: grid; justify-items: end; gap: var(--tud-space-2); }

.pt-loc-actions {
  display: flex;
  align-items: center;
  gap: var(--tud-space-3);
  padding: var(--tud-space-3) var(--tud-space-5);
  border-top: var(--tud-border-hairline) solid var(--tud-color-border-default);
  background: var(--tud-color-bg-sunken);
  flex-wrap: wrap;
}

.pt-loc-actions .pt-status { margin-left: auto; }
.pt-loc-actions .btn { text-decoration: none; }

.pt-empty--locs { max-width: 56ch; min-height: 168px; line-height: 1.6; }
.pt-empty-act { display: block; margin-top: var(--tud-space-4); }

/* ---------- Scan ----------
   The stage is the verdict. Ready state holds the camera; every verdict
   floods the whole stage in the scanner colors both themes share, so the
   answer reads across a counter, not just across a desk. */

.pt-scan { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--tud-space-5); }

.pt-scan-pick {
  padding: var(--tud-space-6);
  border: var(--tud-border-default) solid var(--tud-color-border-default);
  border-radius: var(--tud-radius-lg);
  background: var(--tud-color-bg-surface);
  box-shadow: var(--tud-elevation-e1);
}

.pt-scan-pick-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--tud-space-3);
}

.pt-scan-pick-btn {
  display: grid;
  gap: var(--tud-space-1);
  min-height: 76px;
  padding: var(--tud-space-4) var(--tud-space-5);
  border: var(--tud-border-default) solid var(--tud-color-border-strong);
  border-radius: var(--tud-radius-md);
  background: var(--tud-color-bg-surface);
  color: var(--tud-color-text-primary);
  font-family: var(--tud-font-primary);
  text-align: left;
  cursor: pointer;
  transition: border-color var(--tud-duration-fast) var(--tud-ease-standard),
              background-color var(--tud-duration-fast) var(--tud-ease-standard);
}

.pt-scan-pick-btn:hover { border-color: var(--tud-color-accent-base); background: var(--tud-color-accent-tint); }

.pt-scan-pick-name { font-size: 17px; font-weight: 800; letter-spacing: -0.01em; }
.pt-scan-pick-city { color: var(--tud-color-text-secondary); font-size: 14px; font-weight: 600; }

.pt-scan-change { min-height: 32px; padding: 0 var(--tud-space-2); }

.pt-stage {
  position: relative;
  display: grid;
  place-items: center;
  min-height: clamp(360px, 46vh, 520px);
  border: var(--tud-border-strong) solid var(--tud-color-border-default);
  border-radius: var(--tud-radius-xl);
  background: var(--tud-color-bg-surface);
  box-shadow: var(--tud-elevation-e1);
  overflow: hidden;
  transition: background-color var(--tud-duration-fast) var(--tud-ease-standard);
}

.pt-stage[data-state="checking"] { background: var(--tud-color-bg-sunken); }
.pt-stage[data-state="verified"] { border-color: transparent; color: var(--tud-color-scanner-valid-fg); background: var(--tud-color-scanner-valid-bg); }
.pt-stage[data-state="invalid"] { border-color: transparent; color: var(--tud-color-scanner-invalid-fg); background: var(--tud-color-scanner-invalid-bg); }
.pt-stage[data-state="expired"] { border-color: transparent; color: var(--tud-color-scanner-expired-fg); background: var(--tud-color-scanner-expired-bg); }
.pt-stage[data-state="nooffer"] { border-color: transparent; color: var(--tud-color-text-inverse); background: var(--tud-color-bg-inverse); }

.pt-cam { display: grid; justify-items: center; gap: var(--tud-space-4); width: min(100%, 560px); padding: var(--tud-space-6); }

.pt-cam-idle { display: grid; justify-items: center; gap: var(--tud-space-3); text-align: center; }
.pt-cam-idle .btn { display: inline-flex; align-items: center; gap: var(--tud-space-2); min-height: 54px; }
.pt-cam-idle .fine { max-width: 36ch; }

.pt-cam-video {
  display: block;
  width: 100%;
  max-height: 380px;
  border: var(--tud-border-strong) solid var(--tud-color-border-strong);
  border-radius: var(--tud-radius-md);
  background: var(--tud-color-bg-inverse);
  object-fit: cover;
}

.pt-cam-note {
  margin: 0;
  max-width: 44ch;
  padding: var(--tud-space-3) var(--tud-space-4);
  border: var(--tud-border-hairline) dashed var(--tud-color-border-strong);
  border-radius: var(--tud-radius-md);
  background: var(--tud-color-bg-sunken);
  color: var(--tud-color-text-secondary);
  font-size: 13px;
  font-weight: 600;
  text-align: center;
}

/* Door two. Not a fallback footnote: a desktop till lives here, so the field
   is set at pass-code size and the keyboard alone drives the whole loop. */
.pt-manual {
  padding: var(--tud-space-6);
  border: var(--tud-border-default) solid var(--tud-color-border-default);
  border-radius: var(--tud-radius-lg);
  background: var(--tud-color-bg-surface);
  box-shadow: var(--tud-elevation-e1);
}

.pt-manual-form { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--tud-space-3); }

.pt-manual-label { font-size: 15px; font-weight: 700; }

.pt-manual-row { display: flex; gap: var(--tud-space-3); flex-wrap: wrap; }

.pt-manual-input {
  flex: 1 1 220px;
  min-width: 0;
  min-height: 60px;
  font-family: var(--tud-font-secondary);
  font-size: 27px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-align: center;
  text-indent: 0.22em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}

.pt-manual-row .btn { min-height: 60px; flex: 0 0 auto; }
.pt-manual .fine { max-width: 62ch; }

/* -- verdicts -- */

.pt-verdict {
  display: grid;
  justify-items: center;
  gap: var(--tud-space-2);
  width: 100%;
  max-width: 760px;
  padding: var(--tud-space-8) var(--tud-space-6) var(--tud-space-10);
  text-align: center;
}

.pt-verdict-badge {
  display: grid;
  place-items: center;
  width: 84px;
  height: 84px;
  margin-bottom: var(--tud-space-2);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.18);
}

.pt-stage[data-state="verified"] .pt-verdict-badge { color: var(--tud-color-ramp-neutral-0); background: var(--tud-color-ramp-neutral-950); }

.pt-verdict-word {
  margin: 0;
  font-family: var(--tud-font-secondary);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.85;
}

.pt-stage[data-state="checking"] .pt-verdict-word { color: var(--tud-color-text-secondary); }

.pt-verdict-name { margin: 0; font-size: clamp(34px, 5vw, 56px); line-height: 1.05; font-weight: 800; letter-spacing: -0.02em; overflow-wrap: break-word; max-width: 100%; }
.pt-verdict-sub { margin: 0; font-size: 18px; font-weight: 600; opacity: 0.92; }
.pt-verdict-sub--quiet { font-size: 15px; opacity: 0.8; }
.pt-verdict-say { margin: var(--tud-space-1) 0 0; max-width: 44ch; font-size: 18px; line-height: 1.45; font-weight: 600; opacity: 0.95; }

.pt-verdict-offer {
  display: grid;
  justify-items: center;
  gap: var(--tud-space-1);
  margin-top: var(--tud-space-4);
  padding-top: var(--tud-space-4);
  border-top: var(--tud-border-hairline) solid rgba(255, 255, 255, 0.4);
  width: min(100%, 520px);
}

.pt-verdict-discount {
  margin: 0;
  font-family: var(--tud-font-secondary);
  font-size: clamp(44px, 7vw, 84px);
  line-height: 0.95;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.pt-verdict-offer-name { margin: 0; font-size: 16px; font-weight: 600; opacity: 0.88; }

.pt-verdict-ask { margin: var(--tud-space-4) 0 0; font-size: 17px; font-weight: 700; }

.pt-verdict-picks { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--tud-space-2); width: min(100%, 480px); margin-top: var(--tud-space-2); }

.pt-verdict-pick {
  display: flex;
  align-items: baseline;
  gap: var(--tud-space-3);
  min-height: 56px;
  padding: var(--tud-space-3) var(--tud-space-4);
  border: var(--tud-border-default) solid rgba(255, 255, 255, 0.55);
  border-radius: var(--tud-radius-md);
  background: rgba(255, 255, 255, 0.12);
  color: inherit;
  font-family: var(--tud-font-primary);
  text-align: left;
  cursor: pointer;
  transition: background-color var(--tud-duration-fast) var(--tud-ease-standard);
}

.pt-verdict-pick:hover { background: rgba(255, 255, 255, 0.24); }
.pt-verdict-pick-discount { flex: 0 0 auto; font-family: var(--tud-font-secondary); font-size: 19px; font-weight: 700; white-space: nowrap; }
.pt-verdict-pick-name { min-width: 0; font-size: 14px; font-weight: 600; opacity: 0.92; }

.pt-verdict-foot {
  display: flex;
  align-items: center;
  gap: var(--tud-space-4);
  margin-top: var(--tud-space-5);
  flex-wrap: wrap;
  justify-content: center;
}

.pt-verdict-count {
  font-family: var(--tud-font-secondary);
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  opacity: 0.85;
}

.pt-verdict-count:empty { display: none; }

.pt-verdict-next {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  padding: 0 var(--tud-space-5);
  border: var(--tud-border-default) solid currentColor;
  border-radius: var(--tud-radius-pill);
  background: none;
  color: inherit;
  font-family: var(--tud-font-primary);
  font-size: 14px;
  font-weight: 800;
  cursor: pointer;
}

.pt-verdict-next:hover { background: rgba(255, 255, 255, 0.16); }
.pt-stage[data-state="error"] .pt-verdict-next:hover { background: var(--tud-color-bg-sunken); }

.pt-verdict-bar {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 4px;
  background: currentColor;
  opacity: 0.55;
  transform: scaleX(1);
  transform-origin: left;
  transition: transform 8s linear;
}

/* ---------- Billing ----------
   The plan card is the only place on this surface where the orange is spent on
   a promise rather than on a number, and it earns it: a founding partner is
   here because of that sentence. Everything under it is a ledger. */

.pt-banner-host:not(:empty) { margin-bottom: var(--tud-space-5); }

.pt-banner {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr) max-content;
  align-items: center;
  gap: var(--tud-space-3) var(--tud-space-4);
  padding: var(--tud-space-4) var(--tud-space-5);
  border: var(--tud-border-strong) solid var(--tud-color-status-error-text);
  border-radius: var(--tud-radius-lg);
  background: var(--tud-color-status-error-bg);
  color: var(--tud-color-status-error-text);
}

.pt-banner-icon { flex: 0 0 auto; }
.pt-banner-copy { min-width: 0; }
.pt-banner-head { margin: 0; font-size: 16px; font-weight: 800; letter-spacing: -0.01em; }
.pt-banner-say { margin: var(--tud-space-1) 0 0; max-width: 62ch; font-size: 14px; font-weight: 500; }

.pt-banner .btn {
  border-color: var(--tud-color-status-error-text);
  background: transparent;
  color: var(--tud-color-status-error-text);
}

.pt-banner .btn:hover { background: var(--tud-color-bg-surface); border-color: var(--tud-color-status-error-text); }

.pt-plan { margin-bottom: var(--tud-space-5); }

.pt-plan-card {
  padding: var(--tud-space-6);
  border: var(--tud-border-strong) solid var(--tud-color-border-strong);
  border-radius: var(--tud-radius-lg);
  background: var(--tud-color-bg-surface);
}

/* Founding is the one card that gets the accent, because it is the one card
   carrying a promise instead of a price. */
.pt-plan-card[data-plan="founding"] {
  border-color: var(--tud-color-accent-base);
  background: var(--tud-color-accent-tint);
}

.pt-plan-head { margin: 0; font-size: 28px; line-height: 1.12; font-weight: 800; letter-spacing: -0.02em; }
.pt-plan-card[data-plan="founding"] .pt-plan-head { color: var(--site-accent-text); max-width: 18ch; }

.pt-plan-price {
  display: flex;
  align-items: baseline;
  gap: var(--tud-space-3);
  margin: var(--tud-space-2) 0 0;
  font-family: var(--tud-font-secondary);
  font-size: 32px;
  line-height: 1;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

.pt-plan-term {
  font-family: var(--tud-font-primary);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--tud-color-text-muted);
}

.pt-plan-say { margin: var(--tud-space-3) 0 0; max-width: 68ch; color: var(--tud-color-text-secondary); font-size: 15px; line-height: 1.5; }
.pt-plan-card[data-plan="founding"] .pt-plan-say { color: var(--tud-color-text-primary); }

/* The same fact row the printed invoice uses, so the card on screen and the
   sheet in the merchant's hand are visibly the same document family. */
.pt-plan-facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--tud-space-5);
  margin: var(--tud-space-6) 0 0;
  padding-top: var(--tud-space-5);
  border-top: var(--tud-border-hairline) solid var(--tud-color-border-strong);
}

.pt-plan-fact { min-width: 0; }
.pt-plan-facts dt { color: var(--tud-color-text-muted); font-family: var(--tud-font-secondary); font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; }
.pt-plan-facts dd { margin: var(--tud-space-2) 0 0; min-width: 0; font-size: 16px; font-weight: 700; }

.pt-plan-note { margin: var(--tud-space-5) 0 0; max-width: 62ch; color: var(--tud-color-text-secondary); font-size: 14px; }

.pt-plan-options-card { margin-bottom: var(--tud-space-5); }

.pt-plan-options {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--tud-space-3);
}

.pt-plan-option {
  min-width: 0;
  padding: var(--tud-space-5);
  border: var(--tud-border-hairline) solid var(--tud-color-border-default);
  border-radius: var(--tud-radius-md);
  background: var(--tud-color-bg-canvas);
}

.pt-plan-option[data-plan="founding"] { border-color: var(--tud-color-accent-base); }

.pt-plan-option-head {
  display: flex;
  min-height: 28px;
  align-items: center;
  justify-content: space-between;
  gap: var(--tud-space-3);
}

.pt-plan-option-name { margin: 0; font-size: 19px; line-height: 1.2; }

.pt-plan-option-cap {
  margin: var(--tud-space-2) 0 0;
  color: var(--site-accent-text);
  font-family: var(--tud-font-secondary);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.pt-plan-option-price {
  margin: var(--tud-space-3) 0 0;
  font-family: var(--tud-font-secondary);
  font-size: 21px;
  line-height: 1.25;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.pt-plan-option-say {
  margin: var(--tud-space-3) 0 0;
  color: var(--tud-color-text-secondary);
  font-size: 14px;
  line-height: 1.5;
}

.pt-plan-option-features {
  display: grid;
  gap: var(--tud-space-2);
  margin: var(--tud-space-4) 0 0;
  padding-left: 1.15em;
  color: var(--tud-color-text-secondary);
  font-size: 13px;
  line-height: 1.45;
}

.pt-invoices { display: grid; gap: var(--tud-space-3); }

.pt-invoice {
  display: grid;
  grid-template-columns: minmax(0, 1fr) max-content max-content max-content;
  align-items: center;
  gap: var(--tud-space-3) var(--tud-space-5);
  padding: var(--tud-space-4);
  border: var(--tud-border-hairline) solid var(--tud-color-border-default);
  border-radius: var(--tud-radius-md);
}

.pt-invoice[data-overdue="true"] { border-color: var(--tud-color-status-error-text); background: var(--tud-color-status-error-bg); }

.pt-invoice-ident { min-width: 0; }
.pt-invoice-number { margin: 0; font-family: var(--tud-font-secondary); font-size: 15px; font-weight: 700; letter-spacing: 0.04em; }
.pt-invoice-period { margin: 2px 0 0; color: var(--tud-color-text-muted); font-size: 13px; }

.pt-invoice-money { text-align: right; }
.pt-invoice-amount { margin: 0; font-family: var(--tud-font-secondary); font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.pt-invoice-when { margin: 2px 0 0; color: var(--tud-color-text-muted); font-size: 12px; white-space: nowrap; }
.pt-invoice[data-overdue="true"] .pt-invoice-when { color: var(--tud-color-status-error-text); font-weight: 700; }

.pt-invoices-card .pt-empty { margin: 0; max-width: none; }

/* ---------- Poster ----------
   On screen: a workbench holding the sheet. On paper: the sheet alone. All of
   the sheet's internal sizes are container-query units against its own width,
   so the screen preview and the printed A5 are the same drawing. */

body.pt-poster-open { overflow: hidden; }

.pt-poster {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  background: var(--tud-color-bg-canvas);
}

.pt-poster-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--tud-space-4);
  padding: var(--tud-space-3) var(--tud-space-5);
  border-bottom: var(--tud-border-hairline) solid var(--tud-color-border-default);
  background: var(--tud-color-bg-surface);
  flex-wrap: wrap;
}

.pt-poster-note {
  margin: 0;
  color: var(--tud-color-text-muted);
  font-family: var(--tud-font-secondary);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.pt-poster-stage {
  display: grid;
  place-items: center;
  overflow: auto;
  padding: var(--tud-space-8) var(--tud-space-4);
}

/* Paper is paper in both themes: the ramp colors, never the theme aliases.
   Every size inside the sheet is a cqw against the sheet's own width, so the
   screen preview and the printed A5 are one drawing. The sheet's own box must
   stay clear of cqw: an element is never its own query container, so a length
   written here would silently resolve against the viewport instead. That is
   why the paper margin lives on the child as a margin.

   The single stretched grid row is what lets the child fill the paper minus
   that margin. Giving the child `height: 100%` as well as a margin is what
   pushed the footer off the bottom edge. */
.pt-sheet {
  container-type: inline-size;
  display: grid;
  grid-template-rows: minmax(0, 1fr);
  width: min(92vw, 460px);
  aspect-ratio: 148 / 210;
  background: var(--tud-color-ramp-neutral-0);
  color: var(--tud-color-ramp-neutral-950);
  box-shadow: var(--tud-elevation-e3);
}

.pt-sheet > .pt-empty { margin: var(--tud-space-8) auto; }

.pt-sheet-inner {
  display: flex;
  flex-direction: column;
  min-height: 0;
  margin: 4.2cqw;
  padding: 4.4cqw 5cqw 4cqw;
  border: 1cqw solid var(--tud-color-ramp-neutral-950);
  border-radius: 3.4cqw;
  /* The last defence for a branch name nobody predicted: it crops inside the
     drawn rule rather than bleeding onto the paper's edge. */
  overflow: hidden;
}

.pt-sheet-brand {
  margin: 0;
  font-family: var(--tud-font-secondary);
  font-size: 3.6cqw;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.pt-sheet-head {
  margin: 2.4cqw 0 0;
  font-family: var(--tud-font-primary);
  font-size: 12cqw;
  line-height: 0.98;
  font-weight: 800;
  letter-spacing: -0.03em;
}

.pt-sheet-dot { color: var(--tud-color-accent-base); }

/* The QR and the reader share a baseline; the row is the poster's centre of
   gravity and takes whatever slack the sheet has left. */
.pt-sheet-qr-row { display: flex; align-items: flex-end; gap: 3.4cqw; margin-top: 4.4cqw; }

.pt-sheet-qr {
  flex: 0 0 auto;
  width: 39cqw;
  padding: 2cqw;
  border: 1cqw solid var(--tud-color-ramp-neutral-950);
  border-radius: 2.4cqw;
  background: var(--tud-color-ramp-neutral-0);
}

.pt-sheet-qr svg { display: block; width: 100%; height: auto; }

.pt-sheet-doodle { display: block; width: 27cqw; height: auto; margin-left: auto; }

.pt-sheet-how {
  margin: 4cqw 0 0;
  max-width: 30ch;
  font-size: 4.2cqw;
  line-height: 1.38;
  font-weight: 600;
}

.pt-sheet-foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 3cqw;
  margin-top: auto;
  padding-top: 3cqw;
  border-top: 0.55cqw solid var(--tud-color-ramp-neutral-950);
}

/* Two lines is the branch line's budget. A merchant who names a branch after
   its whole postal address gets the front of it, not a poster that reflows. */
.pt-sheet-loc {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  margin: 0;
  min-width: 0;
  font-family: var(--tud-font-secondary);
  font-size: 4.2cqw;
  line-height: 1.25;
  font-weight: 700;
  overflow: hidden;
  overflow-wrap: break-word;
}

.pt-sheet-site { margin: 0; flex: 0 0 auto; font-size: 3.6cqw; font-weight: 700; color: var(--tud-color-accent-text-on-light); }

/* ---------- In-store report ---------- */

.pt-instore { display: grid; grid-template-columns: minmax(0, 1fr); }
.pt-instore:empty { display: none; }

.pt-instore-title {
  margin: var(--tud-space-10) 0 var(--tud-space-4);
  padding-top: var(--tud-space-6);
  border-top: var(--tud-border-hairline) solid var(--tud-color-border-default);
  font-size: 20px;
  line-height: 26px;
  font-weight: 800;
  letter-spacing: -0.01em;
}

.pt-instore-card { margin-top: var(--tud-space-5); }

.pt-source-seg[data-seg="staff_scan"], .pt-swatch[data-seg="staff_scan"] { background: var(--tud-color-accent-base); }
.pt-source-seg[data-seg="staff_code"], .pt-swatch[data-seg="staff_code"] { background: var(--tud-color-text-secondary); }
.pt-source-seg[data-seg="store_qr"], .pt-swatch[data-seg="store_qr"] { background: var(--tud-color-ramp-accent-200); }

/* ---------- Footer ---------- */

.pt-foot { border-top: var(--tud-border-hairline) solid var(--tud-color-border-default); }

.pt-foot-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--tud-space-4);
  padding-block: var(--tud-space-5);
  color: var(--tud-color-text-muted);
  font-size: 13px;
  flex-wrap: wrap;
}

.pt-foot-nav { display: flex; flex-wrap: wrap; gap: var(--tud-space-3) var(--tud-space-5); }
.pt-foot-nav a { display: inline-flex; min-height: 44px; align-items: center; color: var(--tud-color-text-muted); font-weight: 700; text-decoration: none; }
.pt-foot-nav a:hover { color: var(--site-accent-text); }

/* ---------- Responsive ---------- */

@media (max-width: 1000px) {
  .pt-report-top { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 900px) {
  /* On a tablet or a phone the merchant reads the snippet rather than scrolling
     a nested strip sideways with a thumb. It wraps, and Copy still hands over
     the exact two lines. */
  .pt-snippet-code { white-space: pre-wrap; overflow-wrap: anywhere; }

  .pt-bar-row { flex-wrap: wrap; gap: var(--tud-space-2) var(--tud-space-4); padding-block: var(--tud-space-3); }
  .pt-tabs { order: 3; width: 100%; overflow-x: auto; padding-bottom: 2px; }
  .pt-bar-right { margin-left: auto; }
  .pt-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pt-guide-row { grid-template-columns: minmax(0, 1fr); }
  .pt-plan-options { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 720px) {
  .pt-form { grid-template-columns: minmax(0, 1fr); }
  .pt-offer-body { grid-template-columns: minmax(0, 1fr); }
  .pt-offer-state { justify-items: start; grid-row: 1; }
  .pt-facts { grid-template-columns: minmax(0, 1fr); gap: var(--tud-space-1); }
  .pt-facts dd { margin-bottom: var(--tud-space-3); }

  /* A branch row reads the same way an offer row does: the status chip leads,
     then the name, then the numbers. */
  .pt-loc-body { grid-template-columns: minmax(0, 1fr); }
  .pt-loc-state { justify-items: start; grid-row: 1; }

  /* An invoice row folds the same way, and keeps its state chip at the top
     where the eye already goes. */
  .pt-invoice { grid-template-columns: minmax(0, 1fr); }
  .pt-invoice-money { text-align: left; }
  .pt-invoice-state { grid-row: 1; }
  .pt-invoice .btn { justify-self: start; }
}

@media (max-width: 620px) {
  :root { --pt-gutter: var(--tud-space-4); }

  /* Stacked, so the separator is not left dangling at the end of a wrapped row. */
  .pt-gate-foot { flex-direction: column; gap: 0; }
  .pt-dot { display: none; }

  .pt-statement { grid-template-columns: minmax(0, 1fr); }
  .pt-statement-num { grid-row: auto; }
  .pt-statement-say { align-self: auto; max-width: 30ch; }
  .pt-cell { padding: var(--tud-space-4); }
  .pt-num { font-size: 25px; line-height: 29px; }
  .pt-head-tools { width: 100%; }
  .pt-offer-actions .pt-status { margin-left: 0; width: 100%; }
  .pt-form-foot .btn, .pt-create .btn { flex: 1 1 auto; }

  .pt-loc-actions .pt-status { margin-left: 0; width: 100%; }
  .pt-loc-actions .btn { flex: 1 1 auto; }

  /* Door two on a phone: the field keeps the whole line and the button keeps
     the whole next one, so a thumb cannot miss either. */
  .pt-manual { padding: var(--tud-space-5); }
  .pt-manual-row .btn { flex: 1 1 100%; }
  .pt-manual-input { font-size: 23px; letter-spacing: 0.18em; text-indent: 0.18em; }

  .pt-verdict { padding: var(--tud-space-6) var(--tud-space-4) var(--tud-space-8); }
  .pt-verdict-badge { width: 68px; height: 68px; }
  .pt-verdict-foot { gap: var(--tud-space-3); }

  /* The poster bar is a toolbar, not a caption: the two controls stay on one
     line at thumb size and the sheet label steps out of their way. */
  .pt-poster-bar { gap: var(--tud-space-3); }
  .pt-poster-note { order: -1; width: 100%; }
  .pt-poster-stage { padding: var(--tud-space-5) var(--tud-space-3); }

  /* The alarm keeps its icon beside the sentence; only the action steps down. */
  .pt-banner { grid-template-columns: 24px minmax(0, 1fr); }
  .pt-banner .btn { grid-column: 1 / -1; justify-self: start; }
  .pt-plan-card { padding: var(--tud-space-5); }
  .pt-plan-head { font-size: 24px; }
  .pt-plan-price { font-size: 27px; }
  .pt-plan-facts { grid-template-columns: minmax(0, 1fr); gap: var(--tud-space-4); }
}

@media (prefers-reduced-motion: reduce) {
  .pt-tab, .pt-guide, .pt-copy, .pt-guide-arrow { transition: none; }
  .pt-guide:hover .pt-guide-arrow { transform: none; }

  .pt-scan-pick-btn, .pt-stage, .pt-verdict-pick { transition: none; }
  /* The countdown still says the number; only the sliding rule stands down. */
  .pt-verdict-bar { transition: none; }
}

/* ---------- Print ----------
   Only the poster prints, and only while it is open: a merchant who hits print
   anywhere else in the portal gets the page they are looking at. The sheet is
   sized in millimetres here rather than viewport units, so the container-query
   units inside it resolve against a real A5 and the paper is the same drawing
   as the preview. */

@media print {
  @page { size: A5 portrait; margin: 0; }

  body.pt-poster-open { background: var(--tud-color-ramp-neutral-0); }
  body.pt-poster-open > *:not(#pt-app) { display: none; }
  body.pt-poster-open #pt-app > *:not(.pt-poster) { display: none; }

  body.pt-poster-open .pt-poster {
    position: static;
    display: block;
    background: none;
  }

  body.pt-poster-open .pt-poster-bar { display: none; }

  body.pt-poster-open .pt-poster-stage {
    display: block;
    padding: 0;
    overflow: visible;
  }

  /* Ink the merchant paid for: the QR, the rule and the accent dot are the
     poster, not decoration, so they must survive "background graphics off". */
  body.pt-poster-open .pt-sheet {
    width: 148mm;
    height: 210mm;
    aspect-ratio: auto;
    box-shadow: none;
    break-inside: avoid;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  body.pt-poster-open .pt-sheet * {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}

/* Brand editor: real content controls beside a bounded header preview. */
.pt-brand-workspace { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: 32px; align-items: start; }
.pt-brand-workspace > * { min-width: 0; }
.pt-brand-preview-wrap { position: sticky; top: 110px; }
.pt-preview-label { font-size: 13px; text-transform: uppercase; letter-spacing: .08em; font-weight: 700; margin-bottom: 16px; }
.pt-brand-preview-wrap .brand-masthead { gap: 16px; padding: 20px; margin: 0; }
.pt-brand-preview-wrap .page-title { font-size: 28px; line-height: 1.12; overflow-wrap: anywhere; }
.pt-brand-preview-wrap .lede { font-size: 15px; margin-top: 14px; }
.pt-brand-preview-wrap .brand-layout-compact .brand-masthead { grid-template-columns: minmax(0,1fr) 80px; }
.pt-brand-preview-wrap .brand-identity-logo { width: 56px; height: 56px; }
.pt-cover-placeholder { display: grid; place-items: center; text-align: center; padding: 20px; height: 100%; font-size: 14px; color: var(--tud-color-text-secondary); }
.pt-preview-offer { margin-block: 16px; padding: 20px; border: 1px solid var(--tud-color-border-default); border-radius: 12px; background: var(--tud-color-bg-surface); }
.pt-preview-offer p { font-size: 14px; margin-top: 8px; }
.pt-preset-field { border: 0; padding: 0; margin: 0; min-width: 0; }
.pt-preset-field legend { font-weight: 600; margin-bottom: 10px; }
.pt-preset-options { display: grid; grid-template-columns: repeat(3,minmax(0,1fr)); gap: 10px; }
.pt-preset-options label { display: flex; flex-direction: column; gap: 8px; padding: 12px; border: 1px solid var(--tud-color-border-default); border-radius: 10px; cursor: pointer; }
.pt-preset-options label:has(:checked) { outline: 2px solid var(--tud-color-accent-base); outline-offset: -2px; background: var(--tud-color-bg-sunken); }
.pt-preset-options input { width: 18px; height: 18px; margin: 0; accent-color: var(--tud-color-accent-base); }
.pt-preset-options label > span:last-child { font-size: 12px; font-weight: 400; line-height: 1.4; }
.pt-preset-diagram { height: 42px; display: grid; grid-template-columns: 1fr 1fr; gap: 5px; }
.pt-preset-diagram i { display: block; border-radius: 3px; background: var(--tud-color-border-strong); }
.pt-preset-diagram i:last-child { background: var(--tud-color-accent-base); opacity: .6; }
.pt-preset-spotlight { grid-template-columns: 1fr; }
.pt-preset-compact { grid-template-columns: 1fr 20px; height: 26px; margin-bottom: 16px; }
.pt-upload-label { margin-top: 10px; }
.pt-image-file { width: 100%; min-height: 44px; font: inherit; font-size: 14px; }
.pt-image-preview { display: block; width: min(100%, 280px); height: 160px; object-fit: contain; background: var(--tud-color-bg-sunken); border: 1px solid var(--tud-color-border-default); border-radius: 8px; margin-top: 12px; }
.pt-image-preview.hidden { display: none; }
.pt-form select { min-height: 44px; max-width: 100%; }
@media (max-width: 1000px) { .pt-brand-workspace { grid-template-columns: 1fr; } .pt-brand-preview-wrap { position: static; } }
@media (max-width: 420px) { .pt-preset-options { grid-template-columns: 1fr; } .pt-preset-diagram { display: none; } }

.pt-preset-options label { text-transform: none; letter-spacing: normal; }

/* Brand page v2: a working document editor and the actual public page. */
.pt-brand-workspace { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
#pt-brand-form { padding: 24px; }
.bp-form-heading, .bp-repeat { grid-column: 1 / -1; }
.bp-form-heading { padding-top: 24px; border-top: 1px solid var(--tud-color-border-strong); font-size: 22px; }
.bp-repeat { min-width: 0; border: 0; border-top: 1px solid var(--tud-color-border-strong); padding: 24px 0 0; margin: 16px 0; }
.bp-repeat legend { font-size: 22px; font-weight: 700; padding-right: 16px; }
.bp-repeat-row { padding-block: 20px; border-bottom: 1px solid var(--tud-color-border-default); margin-bottom: 20px; }
.bp-row-head, .pt-preview-toolbar { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 16px; }
.bp-repeat-row .pt-field { margin-block: 16px; }
.bp-swatches { display: grid; grid-template-columns: repeat(6,minmax(0,1fr)); gap: 8px; }
.bp-swatches label { position: relative; display: grid; justify-items: center; gap: 8px; font-size: 12px; text-transform: none; letter-spacing: 0; cursor: pointer; padding: 8px 0; }
.bp-swatches input { position: absolute; top: 18px; width: 18px; height: 18px; z-index: 1; accent-color: var(--tud-color-accent-base); }
.bp-swatch { width: 100%; height: 40px; border-radius: 8px; border: 1px solid var(--tud-color-border-strong); }
.bp-swatch-peach { background: var(--tud-color-deal-panel-1); }
.bp-swatch-pink { background: var(--tud-color-deal-panel-3); }
.bp-swatch-mint { background: var(--tud-color-deal-panel-2); }
.bp-swatch-blue { background: var(--tud-color-deal-panel-5); }
.bp-swatch-yellow { background: var(--tud-color-deal-panel-0); }
.bp-swatch-lime { background: var(--tud-color-deal-panel-4); }
.bp-swatches label:has(:checked) .bp-swatch { outline: 2px solid var(--tud-color-text-primary); outline-offset: 2px; }
.pt-field-error { color: var(--tud-color-status-error-text); font-size: 14px; line-height: 1.5; grid-column: 1 / -1; }
.pt-field-error:empty { display: none; }
#pt-brand-form [aria-invalid="true"] { border-color: var(--tud-color-status-error-text); }
.pt-preset-diagram { height: 76px; width: 100%; grid-template-rows: 1fr 18px; }
.pt-preset-diagram i:nth-child(2) { background: var(--tud-color-deal-panel-2); }
.pt-preset-diagram i:last-child { grid-column: 1 / -1; background: var(--tud-color-accent-base); }
.pt-preset-spotlight { grid-template-columns: 1fr; grid-template-rows: 30px 20px 16px; }
.pt-preset-compact { grid-template-columns: 22px 1fr; grid-template-rows: 20px 1fr; margin-bottom: 0; }
.pt-preview-toolbar h3 { font-size: 20px; }
.pt-brand-preview-wrap label { display: inline-block; margin-right: 12px; font-size: 14px; }
.pt-brand-preview-wrap select { min-height: 44px; border: 1px solid var(--tud-color-border-strong); background: var(--tud-color-bg-surface); color: var(--tud-color-text-primary); font: inherit; border-radius: 8px; padding: 8px; }
.pt-brand-preview-wrap .field-hint { margin-block: 12px; }
#pt-brand-preview { display: block; width: 100%; height: min(72vh,900px); min-height: 500px; border: 1px solid var(--tud-color-border-strong); border-radius: 12px; background: var(--tud-color-bg-canvas); margin-top: 16px; }
#pt-brand-form .pt-form-foot { position: static; background: var(--tud-color-bg-surface); border-top: 1px solid var(--tud-color-border-strong); padding-block: 16px; }
.bp-editor-tools { display: flex; flex-wrap: wrap; gap: 20px; grid-column: 1 / -1; }
.bp-editor-tools a, .bp-back-editor { display: inline-flex; align-items: center; min-height: 44px; font-size: 14px; }
#pt-brand-form, #bp-preview-tools, #bp-save-actions { scroll-margin-top: 120px; }
@media (max-width: 1000px) { .pt-brand-workspace { grid-template-columns: 1fr; } .pt-brand-preview-wrap { position: static; } }
@media (max-width: 420px) {
  #pt-brand-form { padding: 16px; }
  .pt-preset-options { grid-template-columns: 1fr; }
  .pt-preset-options label { display: grid; grid-template-columns: 20px 76px 1fr; align-items: center; }
  .pt-preset-options label > span:last-child { grid-column: 3; }
  .pt-preset-diagram { display: grid; grid-row: span 2; height: 58px; }
  .bp-swatches { grid-template-columns: repeat(3,minmax(0,1fr)); }
  .pt-preview-toolbar { flex-wrap: wrap; }
}
