/* =======================================================================================
   LAZY PROMPTER DESIGN PACKAGE, PANEL LAYER (source: app_lazyprompter design-system/layers/panel.css)
   Loaded by the two operator panels (app_lazyprompter_admin, lazyprompter_seo /admin/panel)
   AFTER lp-brand.css and lp-system.css. It holds only what the panels add on top of the system:
   the panel standard Kenz approved 2026-09-21..22 and the detail-sheet parts. It declares no
   token; every colour comes from the system layer. The raw px values it still carries are
   counted by the raw-value gate (design-system/raw_gate.py) and may only go down.
   Until 2026-09-24 this block lived twice, at the end of each panel's own copy of base.css.
   Edit it here, run python3 design-system/build.py, then export (see design-system/README.md).
   ======================================================================================= */
/* Carried from the panels' old copy of the system (2026-09-24). The web app has since renamed or
   dropped these rules; the panel screens still use every one of them (card links and captions on
   the website panel, field notes and labels in panel forms, the hint icon's tap area, the
   workspace switch pill on a phone). */
.card--link { text-align: left; border-color: var(--lp-stroke-default); color: var(--lp-text-secondary); text-decoration: none; transition: background var(--lp-motion-fast) var(--lp-ease-out), border-color var(--lp-motion-fast) var(--lp-ease-out); }
.card--link:hover { background: var(--lp-wash-subtle); border-color: var(--lp-stroke-light, var(--lp-stroke-default)); }
.card--link:focus-visible { outline: none; box-shadow: var(--lp-focus-ring); }
.card__desc { font-size: var(--lp-text-xs); color: var(--lp-text-tertiary); }
.card__desc + .card__desc { margin-top: var(--lp-space-4); }
.hint-icon::after { content: ''; position: absolute; inset: -7px; }
.field-label { font-size: var(--lp-text-xs); color: var(--lp-text-tertiary); }
.field-note { font-size: var(--lp-text-xs); color: var(--lp-text-tertiary); line-height: 1.5; }
@media (max-width: 768px) { .filter-chip { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; } }

/* =======================================================================================
   PANEL STANDARD (both admin panels), approved screen by screen by Kenz 2026-09-21.
   Canonical text lives in docs/DESIGN-SHARED-VOCABULARY.md "The panels get a standard".
   ======================================================================================= */
/* ---------------------------------------------------------------------------------------
   Điều hành, redrawn 2026-09-21 to the design Kenz approved (canvas EBPB76hf): one focal
   point, four type sizes (44 / 20 / 15 / 12), three text colours, the accent only on what
   needs the owner. Every value below is a base.css token; nothing here invents a colour.
   --------------------------------------------------------------------------------------- */
.panel-section.cockpit, .cockpit { width: 100%; max-width: 760px; min-width: 0; box-sizing: border-box; margin: 0 auto; display: flex; flex-direction: column; gap: 40px; }
.cockpit > * { min-width: 0; }
.screen-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.screen-title { margin: 0; font-size: 20px; font-weight: 600; color: var(--lp-text-primary); }
.range-select {
  min-height: 44px; padding: 0 32px 0 14px; border: 1px solid var(--lp-stroke-default); border-radius: 10px;
  background: transparent; color: var(--lp-text-secondary); font: inherit; font-size: 12px; cursor: pointer;
  appearance: none; -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 17px) 50%, calc(100% - 12px) 50%; background-size: 5px 5px; background-repeat: no-repeat;
}
.cockpit__todo { display: flex; flex-direction: column; gap: 16px; }
.cockpit__focal { display: flex; align-items: baseline; gap: 12px; }
.cockpit__focal-num { font-size: 44px; font-weight: 600; line-height: 1; color: var(--lp-accent-base); }
.cockpit__focal-label { font-size: 15px; color: var(--lp-text-secondary); }
.cockpit__list { background: var(--lp-bg-surface); border-radius: 16px; overflow: hidden; }
.cockpit__row, .cockpit__subrow {
  width: 100%; min-height: 64px; box-sizing: border-box; display: flex; align-items: center; gap: 16px;
  padding: 12px 20px; border: 0; background: transparent; color: var(--lp-text-primary); font: inherit;
  text-align: left; text-decoration: none; cursor: pointer;
}
.cockpit__row + .cockpit__row, .cockpit__sub + .cockpit__row, .cockpit__row + .cockpit__sub { border-top: 1px solid var(--lp-bg-elevated); }
.cockpit__row:hover, .cockpit__subrow:hover { background: var(--lp-bg-elevated); }
.cockpit__row--static { cursor: default; }
.cockpit__row--static:hover { background: transparent; }
.cockpit__sub { background: var(--lp-bg-base); }
.cockpit__subrow { min-height: 56px; padding-left: 44px; }
.cockpit__dot { width: 8px; height: 8px; border-radius: 4px; flex-shrink: 0; background: var(--lp-stroke-strong); }
.cockpit__dot--hot { background: var(--lp-accent-base); }
.cockpit__row-body { flex-grow: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.cockpit__row-title { font-size: 15px; color: var(--lp-text-primary); }
.cockpit__row-desc { font-size: 12px; color: var(--lp-text-tertiary); }
.cockpit__row-amount { font-size: 15px; font-weight: 500; color: var(--lp-text-primary); white-space: nowrap; }
.cockpit__revenue { display: flex; align-items: flex-end; justify-content: space-between; gap: 40px; }
.cockpit__revenue-num { display: flex; flex-direction: column; gap: 8px; }
.stat__label { font-size: 12px; color: var(--lp-text-tertiary); }
.cockpit__big { font-size: 44px; font-weight: 600; line-height: 1; color: var(--lp-text-primary); }
.cockpit__spark { flex-grow: 1; max-width: 560px; height: 72px; color: var(--lp-text-secondary); }
.stat-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; padding-top: 24px; border-top: 1px solid var(--lp-bg-surface); }
.stat { display: flex; flex-direction: column; gap: var(--lp-space-8); }
.stat__value { font-size: 15px; font-weight: 500; color: var(--lp-text-primary); }
@media (max-width: 767px) {
  .panel-section.cockpit, .cockpit { gap: 32px; }
  .cockpit__row, .cockpit__subrow { padding: 12px 16px; gap: 14px; }
  .cockpit__subrow { padding-left: 38px; }
  .cockpit__revenue { flex-direction: column; align-items: stretch; gap: 12px; }
  .cockpit__spark { max-width: none; height: 56px; }
  .stat-row { grid-template-columns: 1fr 1fr; gap: 20px; padding-top: 20px; }
}

/* ---------------------------------------------------------------------------------------
   List screens, drawn and approved 2026-09-21 (canvas EBPB76hf, "Bán hàng"): title, text
   tabs, one search field with one filter button, then one card of rows. Same row grammar
   as the Điều hành list: dot, who or what, one quiet line, the number and when.
   --------------------------------------------------------------------------------------- */
.panel-section.list-screen, .list-screen { width: 100%; max-width: 760px; min-width: 0; box-sizing: border-box; margin: 0 auto; display: flex; flex-direction: column; gap: 24px; }
.list-screen > * { min-width: 0; }
.text-tabs { display: flex; gap: 16px; border-bottom: 1px solid var(--lp-bg-surface); overflow-x: auto; }
.text-tab { min-height: 44px; min-width: 44px; padding: 0 4px; border: 0; background: transparent; color: var(--lp-text-tertiary); font: inherit; font-size: 15px; cursor: pointer; flex-shrink: 0; }
.text-tab--active { color: var(--lp-text-primary); box-shadow: inset 0 -2px 0 var(--lp-accent-base); }
.list-tools { display: flex; gap: 8px; }
.list-tools__spacer { flex-grow: 1; }
.list-search { flex-grow: 1; min-width: 0; height: 48px; display: flex; align-items: center; gap: 10px; padding: 0 16px; border-radius: 12px; background: var(--lp-bg-surface); color: var(--lp-text-tertiary); box-sizing: border-box; }
.list-search__input { flex-grow: 1; min-width: 0; border: 0; background: transparent; color: var(--lp-text-primary); font: inherit; font-size: 15px; outline: none; }
.list-search:focus-within { box-shadow: 0 0 0 2px var(--lp-stroke-strong); }
.list-filter { position: relative; width: 48px; height: 48px; flex-shrink: 0; border: 0; border-radius: 12px; background: var(--lp-bg-surface); color: var(--lp-text-secondary); display: flex; align-items: center; justify-content: center; cursor: pointer; }
.list-filter--on { color: var(--lp-text-primary); }
.list-filter__dot { position: absolute; top: 10px; right: 10px; width: 8px; height: 8px; border-radius: 4px; background: var(--lp-accent-base); }
.list-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.list-card { background: var(--lp-bg-surface); border-radius: 16px; overflow: hidden; }
.list-row { width: 100%; min-height: 60px; box-sizing: border-box; display: flex; align-items: center; gap: 14px; padding: 10px 20px; border: 0; background: transparent; color: var(--lp-text-primary); font: inherit; text-align: left; cursor: pointer; }
.list-row + .list-row { border-top: 1px solid var(--lp-bg-elevated); }
.list-row:hover { background: var(--lp-bg-elevated); }
.list-row--static { cursor: default; }
.list-row--static:hover { background: transparent; }
.list-row__dot { width: 8px; height: 8px; border-radius: 4px; flex-shrink: 0; background: transparent; }
.list-row__dot--hot { background: var(--lp-accent-base); }
.list-row__main { flex-grow: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.list-row__title { font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-row__desc { font-size: 12px; color: var(--lp-text-tertiary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-row__side { flex-shrink: 0; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.list-row__value { font-size: 15px; font-weight: 500; white-space: nowrap; }
.list-foot { display: flex; align-items: center; justify-content: center; gap: 16px; font-size: 12px; color: var(--lp-text-tertiary); }
.list-more { min-height: 44px; padding: 0 16px; border: 1px solid var(--lp-stroke-default); border-radius: 10px; background: transparent; color: var(--lp-text-secondary); font: inherit; font-size: 12px; cursor: pointer; }
@media (max-width: 767px) {
  .panel-section.list-screen, .list-screen { gap: 20px; }
  .list-row { padding: 10px 16px; }
}

/* Affiliate, drawn 2026-09-21: sections with a quiet 12px label, and the funnel as three
   big numbers where only the weakest step is accented. */
.section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.range-select--sm { min-height: 44px; }
.funnel-block { display: flex; flex-direction: column; gap: 16px; }
.funnel-steps { display: flex; align-items: flex-end; gap: 32px; }
.funnel-steps__step { display: flex; flex-direction: column; gap: 6px; }
.funnel-steps__num { font-size: 44px; font-weight: 600; line-height: 1; color: var(--lp-text-primary); }
.funnel-steps__num--hot { color: var(--lp-accent-base); }
.funnel-steps__arrow { font-size: 20px; color: var(--lp-stroke-strong); padding-bottom: 20px; }
.funnel-block__leak { margin: 0; font-size: 15px; color: var(--lp-text-secondary); }
.list-section { display: flex; flex-direction: column; gap: 12px; }
.list-section__empty { margin: 0; font-size: 15px; color: var(--lp-text-tertiary); }
a.list-row { text-decoration: none; }
@media (max-width: 767px) { .funnel-steps { gap: 16px; } }

/* Engine hub, drawn 2026-09-21: one focal number on a line, doors as rows with a chevron. */
.focal-line { display: flex; align-items: baseline; gap: 12px; }
.focal-line__num { font-size: 44px; font-weight: 600; line-height: 1; color: var(--lp-text-primary); }
.focal-line__label { font-size: 15px; color: var(--lp-text-secondary); }
.list-row__chev { flex-shrink: 0; color: var(--lp-stroke-strong); }
.stat-row--3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 767px) { .stat-row--3 { grid-template-columns: 1fr 1fr; } }

/* Sub-screens, drawn 2026-09-21: a back link over the title, and inner lists that sit in
   the parent's column without their own max width. */
.sub-head { display: flex; flex-direction: column; gap: 8px; }
.back-link { align-self: flex-start; min-height: 44px; padding: 0; border: 0; background: transparent; color: var(--lp-text-tertiary); font: inherit; font-size: 12px; cursor: pointer; }
.back-link:hover { color: var(--lp-text-secondary); }
.list-screen--inner { max-width: none; margin: 0; }
.list-tools--end { justify-content: flex-end; }
.list-card--form { padding: 20px; display: flex; flex-direction: column; gap: 16px; }
.form-foot { display: flex; align-items: center; justify-content: flex-end; gap: 12px; }
.form-foot__err { color: var(--lp-accent-base); }

/* Rows that open in place (Prompt engine, Cấu hình), drawn 2026-09-21. */
.row-editor { border-top: 1px solid var(--lp-bg-elevated); padding: 20px; display: flex; flex-direction: column; gap: 16px; background: var(--lp-bg-base); }
.row-editor__switches { display: flex; flex-wrap: wrap; align-items: center; gap: 24px; }
.row-editor__grow { flex-grow: 1; }
.switch-line { display: inline-flex; align-items: center; gap: 10px; font-size: 15px; color: var(--lp-text-secondary); }
.list-row__chev--open { transform: rotate(90deg); }
.form-foot--split { justify-content: space-between; flex-wrap: wrap; }
.form-foot__left, .form-foot__right { display: inline-flex; align-items: center; gap: 12px; flex-wrap: wrap; }

/* Added 2026-09-21 with the website screens: an accented focal number, and message text inside an open row. */
.focal-line__num--hot { color: var(--lp-accent-base); }
.row-editor__text { margin: 0; font-size: 15px; line-height: 1.5; color: var(--lp-text-primary); white-space: pre-wrap; }
a.stat { text-decoration: none; color: var(--lp-text-primary); min-height: 44px; }
a.stat:hover .stat__value { text-decoration: underline; }

/* Content lists, drawn 2026-09-21: a picture where the table has one, and a whole row that opens. */
.list-row--content { cursor: pointer; }
.list-row__thumb { width: 44px; height: 44px; flex-shrink: 0; border-radius: 10px; overflow: hidden; background: var(--lp-bg-elevated); }
.list-row__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* A switch is drawn 31px tall but must take a 44px tap: the hit area grows, the drawing does not. */
button.lp-switch::before { content: ""; position: absolute; top: -7px; bottom: -7px; left: 0; right: 0; }
/* A row that opens AND carries its own switch: the opening part is its own button, so a
   switch never sits inside another button. */
.list-row__hit { flex-grow: 1; min-width: 0; min-height: 44px; display: flex; align-items: center; gap: 14px; padding: 0; border: 0; background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.field-count { display: flex; justify-content: space-between; gap: 12px; }

/* Post editor, drawn 2026-09-21: body first, a Google rail beside it, save within reach. */
.post-edit { padding-bottom: 88px; }
.post-edit__cols { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 40px; align-items: start; }
.post-edit__main, .post-edit__rail { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.post-edit__title { min-height: 52px; padding: 0; border: 0; background: transparent; color: var(--lp-text-primary); font: inherit; font-size: 20px; font-weight: 600; outline: none; }
.post-edit__cover { position: relative; min-height: 180px; border-radius: 16px; overflow: hidden; background: var(--lp-bg-elevated); display: flex; align-items: center; justify-content: center; }
.post-edit__cover img { width: 100%; max-height: 320px; object-fit: cover; display: block; }
/* A real <button> since 2026-09-21: it opens the media library rather than wrapping a file
   input, so it needs the control reset a <label> never did. */
.post-edit__cover-pick { position: absolute; right: 12px; bottom: 12px; min-height: 44px; display: inline-flex; align-items: center; padding: 0 14px; border: 0; border-radius: 10px; background: rgba(0, 0, 0, 0.72); color: #FFFFFF; font: inherit; font-size: 12px; cursor: pointer; }
.post-edit__alt { display: flex; gap: 8px; align-items: center; }
.post-edit__alt .input { flex-grow: 1; }
.post-edit__tools { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; padding-bottom: 4px; border-bottom: 1px solid var(--lp-bg-elevated); }
.tool-btn { min-width: 44px; height: 44px; padding: 0 8px; border: 0; border-radius: 8px; background: transparent; color: var(--lp-text-secondary); font: inherit; font-size: 15px; font-weight: 600; cursor: pointer; }
.tool-btn:hover { background: var(--lp-bg-elevated); }
.tool-btn--on { color: var(--lp-text-primary); background: var(--lp-bg-elevated); }
.post-edit__words { margin-left: auto; font-size: 12px; color: var(--lp-text-tertiary); }
.post-edit__live { justify-content: space-between; }
.post-edit__bar { position: sticky; bottom: 0; z-index: 5; display: flex; align-items: center; justify-content: flex-end; gap: 12px; min-height: 72px; margin-top: 24px; padding: 12px 0 calc(12px + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--lp-bg-elevated); background: var(--lp-bg-base); }
.post-edit__bar > .list-row__desc:first-child { margin-right: auto; }
@media (max-width: 900px) { .post-edit__cols { grid-template-columns: minmax(0, 1fr); } }
.post-edit__alt .list-more { white-space: nowrap; }

/* ---------------------------------------------------------------------------------------
   Thư viện ảnh and the picker, drawn 2026-09-21 (canvas EBPB76hf, "Thư viện ảnh" and
   "Chọn ảnh từ bài viết"). One grid grammar serves both: the library puts a detail panel
   beside it, the picker puts it in a modal. Every value below is a base.css token.
   --------------------------------------------------------------------------------------- */
.media { display: flex; gap: 24px; align-items: flex-start; }
.media__main { flex-grow: 1; min-width: 0; display: flex; flex-direction: column; gap: 16px; }
.media__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.media__grid--wide { grid-template-columns: repeat(4, 1fr); }
.media__cell {
  display: flex; flex-direction: column; gap: 8px; padding: 0; border: 0; background: transparent;
  color: var(--lp-text-primary); font: inherit; text-align: left; cursor: pointer; min-width: 0;
}
.media__thumb {
  width: 100%; aspect-ratio: 1 / 1; border-radius: 12px; background: var(--lp-bg-surface);
  display: block; object-fit: cover;
}
/* The ring sits OUTSIDE the corner radius, so a selected thumbnail keeps its shape instead of
   growing a square border. Same 2px the drawing uses. */
.media__cell--on .media__thumb { box-shadow: 0 0 0 2px var(--lp-accent-base); }
.media__cell:hover .media__thumb { box-shadow: 0 0 0 2px var(--lp-stroke-strong); }
.media__cell--on:hover .media__thumb { box-shadow: 0 0 0 2px var(--lp-accent-base); }
.media__cell:focus-visible .media__thumb { box-shadow: 0 0 0 2px var(--lp-accent-base); }
/* The caption under a thumbnail is the smallest text on any panel screen, so it is also the
   easiest place to fall under the readable floor. The drawing dims "Chưa dùng" to #5D5E60,
   which measures 2.10:1 on the surface it sits on (consumer-channel audit, 2026-09-21); the
   quieter of the two stays quieter, but on the tertiary token, which is the dimmest value
   base.css has that still clears 4.5:1. */
.media__use { font-size: 12px; color: var(--lp-text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.media__use--idle { color: var(--lp-text-tertiary); }

.media__aside {
  width: 280px; flex-shrink: 0; box-sizing: border-box; display: flex; flex-direction: column; gap: 16px;
  padding: 20px; border-radius: 16px; background: var(--lp-bg-surface); align-self: flex-start;
}
.media__preview { width: 100%; aspect-ratio: 4 / 3; border-radius: 12px; background: var(--lp-bg-elevated); display: block; object-fit: contain; }
.media__facts { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.media__name { font-size: 15px; overflow-wrap: anywhere; }
.media__meta { font-size: 12px; color: var(--lp-text-tertiary); }
.media__where { display: flex; flex-direction: column; gap: 8px; }
.media__where-link {
  min-height: 44px; display: flex; align-items: center; padding: 0; border: 0; background: transparent;
  color: var(--lp-text-primary); font: inherit; font-size: 15px; text-align: left; cursor: pointer;
  text-decoration: underline; overflow-wrap: anywhere;
}
.media__where-link:hover { color: var(--lp-accent-base); }
.media__acts { display: flex; flex-wrap: wrap; gap: 8px; }
.media__note { font-size: 12px; color: var(--lp-text-tertiary); }
.media__empty { margin: 0; font-size: 15px; color: var(--lp-text-tertiary); }

/* The desktop board says "Tải ảnh lên", the phone board says "Tải lên", and on a 390px screen
   the long one wraps the button onto two lines. Both words are in the markup and the screen
   width picks one, so each board gets the label it was drawn with. */
.media__short { display: none; }

@media (max-width: 767px) {
  /* The phone board draws the GRID as the screen. So the detail stops being a right-hand
     column and becomes a compact card above the grid: a tapped image explains itself where
     the thumb was, and the grid is still there underneath.
     The first version of this rule only moved the panel and kept its shape, which on a 390px
     phone meant a 4:3 preview about 290px tall plus its facts: the detail filled the screen
     and pushed every thumbnail below the fold, which is the opposite of what the board draws
     (measured 2026-09-21 at 390x844). Laid out as a row, it costs about a quarter of that. */
  .media { flex-direction: column-reverse; gap: 16px; }
  .media__aside { width: 100%; flex-direction: row; flex-wrap: wrap; align-items: flex-start; gap: 12px; padding: 16px; }
  .media__preview { width: 96px; height: 96px; aspect-ratio: auto; flex-shrink: 0; }
  .media__facts, .media__where { flex: 1 1 150px; min-width: 0; }
  .media__acts, .media__note { flex-basis: 100%; }
  .media__grid--wide { grid-template-columns: repeat(3, 1fr); }
  .media__long { display: none; }
  .media__short { display: inline; }
}

/* ONE LOADING LANGUAGE (2026-09-21). Every panel screen said "Đang tải..." in a line of text,
   then swapped that line for a list 300px taller: the whole page jumped. The loading state now
   takes the shape of what arrives, a list card of breathing rows, with the same breathe as the
   web app's skeleton. The words stay in the element for screen readers. Screens that draw their
   own skeleton inside .panel-loading keep it (:has(*) leaves them alone). */
div.panel-loading:not(:has(*)) {
  position: relative; min-height: 300px; padding: 0; overflow: hidden;
  color: transparent; font-size: 0; text-align: left;
}
div.panel-loading:not(:has(*))::before {
  content: ""; position: absolute; inset: 0; border-radius: 16px;
  background-color: var(--lp-bg-surface);
  background-image: repeating-linear-gradient(to bottom, transparent 0, transparent 59px, var(--lp-bg-base) 59px, var(--lp-bg-base) 60px);
  animation: skeleton-breathe var(--lp-anim-skeleton) ease-in-out infinite;
}

/* MODAL FOOTER (2026-09-21). The footer spread its buttons edge to edge (space-between), so
   three controls of three shapes scattered across the width, and every modal repeated "Đóng"
   beside the × that already closes it, as do Escape and the backdrop. Now: actions sit together
   on the right, the primary last; a status line takes the left; one height for all; a link
   styled as a button is not underlined. Closing is the ×'s job alone. */
.modal__footer { justify-content: flex-end; gap: 12px; }
.modal__footer > .field-group-note, .modal__footer > .list-row__desc { margin-right: auto; }
.modal__footer .btn { min-height: 44px; padding-left: 18px; padding-right: 18px; }
.modal__footer a.btn { text-decoration: none; }

/* FOUR SIZES, EVERYWHERE (2026-09-21). The approved standard names four type sizes (44, 20, 15,
   12). A check added to demo/screen-audit.mjs the same day found the furniture around every
   screen still on older sizes: 13px navigation and account name, 14px brand, 11-13px buttons,
   notification rows and role line, an 18px dialog title. Reading text is 15, secondary is 12,
   titles are 20. */
body .logo-text, body .nav-item, body .nav-item span { font-size: var(--lp-text-base); }
body .attention-row__title { font-size: var(--lp-text-md); }
body .attention-row__desc { font-size: var(--lp-text-sm); }
body .modal__title { font-size: 20px; }
/* Inside dialogs and forms: labels, notes and variable chips are secondary text (12), anything
   unclassed in a dialog body reads at 15. The e-mail preview is exempt: it shows the message the
   way the customer's mail app renders it, not panel text. */
body .field-group-label, body .field-group-note, body .pill, body .save-note, body .save-note * { font-size: 12px; }
body .modal__body { font-size: 15px; }

/* BUTTONS (convention approved 2026-09-21, canvas "Quy ước nút"): one shape, the web app's pill;
   one height, 44px on every screen size; 15px text; width follows the words. Three kinds:
   Chính (.btn--primary, filled, at most one per layer, last on the right), Phụ (.btn--outline
   and .list-more, a 1px ring), Chữ (.back-link, no ring, no fill). Before this the same role
   came as a 24px pill on desktop and a 10px-cornered rectangle with 12px text. */
body .btn, body .btn--sm, body .list-more {
  height: var(--lp-height-sm); min-height: var(--lp-height-sm); padding: 0 var(--lp-space-16); border-radius: 999px;
  font-size: var(--lp-text-base); font-weight: 500; white-space: nowrap;
}
@media (max-width: 767px) { body .btn, body .btn--sm, body .list-more { height: 44px; min-height: 44px; } }
body .list-more { border: 1px solid var(--lp-stroke-strong); background: transparent; color: var(--lp-text-primary); }
body .back-link { min-height: 32px; font-size: var(--lp-text-base); color: var(--lp-text-secondary); }
/* ...but not below the tap floor. The 32px above was the desktop size of the Chữ button; on a
   phone it made the one control that walks OUT of a stacked sheet the smallest target on screen.
   Nothing measured it until 2026-09-22, because no screen in demo/screen-audit.mjs opened a sheet
   with another sheet under it, which is the only place .back-link renders. Until 2026-09-24 the
   website panel's copy of this block lacked the fix; one layer now serves both panels. */
@media (max-width: 767px) { body .back-link { min-height: 44px; } }

/* WHERE AM I (approved 2026-09-21, canvas "Điều hướng"): the path sits in the top bar, which
   stays put while the page scrolls. Whole path on a wide screen, one level up on a phone. */
.topbar__left { display: flex; align-items: center; gap: 8px; min-width: 0; }
.crumbs { display: flex; align-items: center; min-width: 0; overflow: hidden; }
.crumbs__step { display: inline-flex; align-items: center; min-width: 0; }
.crumbs__link { min-height: 44px; display: inline-flex; align-items: center; font-size: 15px; color: var(--lp-text-secondary); text-decoration: none; white-space: nowrap; }
.crumbs__link:hover { color: var(--lp-text-primary); }
.crumbs__here { font-size: 15px; color: var(--lp-text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crumbs__sep { margin: 0 8px; color: var(--lp-text-tertiary); font-size: 15px; }
.crumbs-back { display: none; min-height: 44px; align-items: center; padding: 0 8px; font-size: 15px; color: var(--lp-text-primary); text-decoration: none; white-space: nowrap; }
@media (max-width: 767px) {
  .crumbs { display: none; }
  .crumbs-back { display: inline-flex; }
}

/* THE SHARED SHELL (canvas "Khung chung", 2026-09-22). One shell for the web app and both panels:
   brand "Lazy Prompter" with the surface named small beside it, the web app's line icons and
   chevron, and in the top bar's right corner, in a fixed order, search, create, notifications,
   account. The account is a round initial, not a card with a caret at the sidebar's foot. */
.nav-item__icon.icon { width: 18px; height: 18px; flex-shrink: 0; }
.lp-avatar { width: 32px; height: 32px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center;
  background: var(--lp-bg-elevated); color: var(--lp-text-primary); font-size: 12px; font-weight: 600; }
@media (min-width: 768px) { body .topbar__toggle-mobile { display: none; } }
body .sidebar__header { display: flex; align-items: center; gap: 4px; }
body .sidebar__toggle { flex-shrink: 0; }
/* The phone drawer casts its lift shadow only while it is out (2026-09-27). The system layer gives a parked
   drawer no shadow (its 40px blur banded the left edge of every phone screen from -100%) and lifts the web app's
   open state, .sidebar--open-mobile; the panels open theirs with .sidebar--open, so that state is named here. */
@media (max-width: 768px) { .sidebar--open { box-shadow: var(--lp-shadow-l); } }
body .topbar .icon-btn .icon { width: 20px; height: 20px; }

/* TYPE AND SIZE FROM THE WEB APP (2026-09-22). Kenz: the web app reads calmer, roomier, more
   premium. Measured the same parts side by side: the web app sets navigation at 13px, list titles
   at 14px/500, section labels at 12px/600, page titles at 18px, hero numbers at 24-28px, buttons
   32px tall with 13px text on a desktop (44px on a phone). The panel standard had invented its own
   scale (15 / 20 / 44, buttons 44px everywhere), about a size heavier at every step, which is
   exactly the crowding he felt. The panels now use the web app's tokens, the reference surface's
   own scale, so a value is never picked twice. */
body .screen-title, body .modal__title { font-size: var(--lp-text-xl); }
body .cockpit__focal-num, body .focal-line__num, body .funnel-steps__num, body .cockpit__big { font-size: var(--lp-text-3xl); }
body .list-row__title, body .cockpit__row-title { font-size: var(--lp-text-md); font-weight: 500; }
body .list-row__value, body .cockpit__row-amount, body .stat__value { font-size: var(--lp-text-md); }
body .list-row__desc, body .cockpit__row-desc { font-size: var(--lp-text-sm); }
body .stat__label { font-size: var(--lp-text-sm); font-weight: 600; }
body .text-tab, body .crumbs__link, body .crumbs__here, body .crumbs__sep, body .crumbs-back, body .switch-line,
body .row-editor__text, body .focal-line__label, body .cockpit__focal-label, body .list-search__input,
body .funnel-block__leak, body .list-section__empty, body .modal__body { font-size: var(--lp-text-base); }
body .list-search { height: var(--lp-height-md); }
body .list-filter { width: var(--lp-height-md); height: var(--lp-height-md); }
@media (max-width: 767px) { body .list-search { height: 44px; } body .list-filter { width: 44px; height: 44px; } }

/* Sidebar rhythm, as the web app spaces it: 24px between groups (the web app's aside gap, measured),
   4px inside a group. The panel's groups sit inside one <nav>, so the gap is set there. */
body .sidebar__nav { display: flex; flex-direction: column; gap: var(--lp-space-24); }

/* SCREEN GRAMMAR FROM THE WEB APP (approved on canvas "Kiểu màn chung", 2026-09-22). Measured on
   the web app's History screen: content starts at the left, up to 1040px wide with 24px padding
   (.page-inner); a heading is an 18px title over a 13px secondary line (.content-sub); groups are
   titled in 12px/600 capitals spaced 0.6px in the tertiary grey; every item is its own card, 1px
   border, 12px corners, 16px inside, 12px apart. The panels used a centred 760px column, no
   subtitle, lower-case labels and rows fused into one card with hairlines. */
body .panel-section.list-screen, body .list-screen, body .panel-section.cockpit, body .cockpit { max-width: 1040px; margin: 0; }
body .list-screen--inner { max-width: none; }
body .panel-scroll { padding: var(--lp-space-24); }
.screen-heading { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
body .screen-heading .content-sub { margin: 0; font-size: var(--lp-text-base); color: var(--lp-text-secondary); }
.section-label, body .list-section > .stat__label, body .section-head > .stat__label, body .cockpit__revenue-num > .stat__label {
  font-size: var(--lp-text-sm); font-weight: 600; letter-spacing: 0.6px; text-transform: uppercase; color: var(--lp-text-tertiary);
}
body .list-card, body .cockpit__list { background: transparent; border-radius: 0; overflow: visible; display: flex; flex-direction: column; gap: 12px; }
body .list-card > .list-row, body .cockpit__list > .cockpit__row {
  background: var(--lp-bg-surface); border: 1px solid var(--lp-stroke-default); border-radius: 12px; padding: 16px;
}
body .list-card > .list-row + .list-row, body .cockpit__list > .cockpit__row + .cockpit__row { border-top: 1px solid var(--lp-stroke-default); }
body .list-card > .list-row--static:hover { background: var(--lp-bg-surface); }
body .list-card > .list-row[aria-expanded="true"], body .cockpit__list > .cockpit__row[aria-expanded="true"] { border-radius: 12px 12px 0 0; }
body .list-card > .row-editor, body .cockpit__list > .cockpit__sub {
  margin-top: -12px; border: 1px solid var(--lp-stroke-default); border-top: 0; border-radius: 0 0 12px 12px; background: var(--lp-bg-base); overflow: hidden;
}
body .list-card--form { background: var(--lp-bg-surface); border: 1px solid var(--lp-stroke-default); border-radius: 12px; padding: 16px; }
body .stat-row { border-top: 0; padding-top: 0; gap: 12px; }
body .stat-row > .stat, body .stat--card { padding: 16px; background: var(--lp-bg-surface); border: 1px solid var(--lp-stroke-default); border-radius: 12px; }
body .stat__value--big { font-size: var(--lp-text-3xl); font-weight: 600; }
body .cockpit__revenue { padding: 16px; background: var(--lp-bg-surface); border: 1px solid var(--lp-stroke-default); border-radius: 12px; align-items: center; }
body .list-card > .list-card__group { margin-top: 12px; }
body .list-card > .list-card__group:first-child { margin-top: 0; }
/* The range picker takes the web app's control size: a 32px pill on a desktop, 44px on a phone. */
body .range-select { height: var(--lp-height-sm); border-radius: 999px; font-size: var(--lp-text-base); padding-top: 0; padding-bottom: 0; }
@media (max-width: 767px) { body .range-select { height: 44px; } }

/* Every panel dialog is the web app's SHEET KIT (canvas "Khung chi tiết", 2026-09-22). The panels
   used to carry a verbatim copy of it here; they now read it from the system layer itself. */

/* Panel footers inside the sheet: a status line on the left, the actions together on the right. */
body .lp-sheet__footer .save-note, body .lp-sheet__footer > span:not(.btn) { margin-right: auto; font-size: var(--lp-text-sm); color: var(--lp-text-tertiary); }
body .lp-sheet__footer a.btn { text-decoration: none; }

/* Inside a detail sheet (canvas "Khung chi tiết"): a meta line under the title, six numbers as a
   grid of small cards (3 across from 768px, 2 on a phone), and quiet detail rows. */
.sheet-meta { margin: 0; font-size: var(--lp-text-sm); color: var(--lp-text-tertiary); }
.lp-sheet__scroll > .section-label { display: block; margin: 20px 0 10px; }
.sheet-stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
@media (min-width: 768px) { .sheet-stats { grid-template-columns: repeat(3, 1fr); } }
.sheet-stats .stat--card { padding: 12px 14px; background: var(--lp-bg-base); }
.sheet-kv__row { display: flex; justify-content: space-between; gap: 12px; padding: 10px 0; border-top: 1px solid var(--lp-bg-elevated); font-size: var(--lp-text-base); }
.sheet-kv__row > span:first-child { color: var(--lp-text-tertiary); }
.lp-sheet__scroll .list-card > .list-row { background: var(--lp-bg-base); }
