/* modals.css — /p/my modal shells (Edit Profile, Edit Ticket, Verify, Force
   Password). Reuses .auth-modal / .auth-input / .auth-btn / .auth-emoji /
   .auth-swatch etc. from auth.css (linked alongside this file) for visual
   consistency; only adds what auth.css doesn't have.
   Design source: MEMBERSHIP_REQUIREMENTS §15.13–§15.16. */

.my-modal__card--wide { max-width: 400px; }

/* Frozen header (2026-08-16 ask) — same technique as the two existing
   frozen-header modals on the site, `.nt-detail` (giveaway.css §9.3) and
   `.sp-modal__*` (sponsor.css): .auth-modal__card's own overflow-y:auto
   (auth.css) scrolls the WHOLE card as one box, title/✕ included, so a
   position:sticky header is still inside that same scrolling box — the
   native scrollbar spans the space "behind" it too. Instead, overflow on
   the card itself is turned off and moved onto a single inner wrapper
   (`.my-modal__scroll`, built in modals.js) holding everything below the
   head, so the head simply isn't part of any scrolling box.
   .my-modal__card--wide is the only `wide` modal on the site (Edit
   Profile), so this scopes safely — matches .nt-detail's own comment that
   .auth-modal__head is shared sitewide and must stay scoped per-variant.
   Card padding moves to 0 here — head and scroll each carry their own full
   padding instead — so the scroll wrapper's own edge (where its scrollbar
   sits) reaches the card's true edge rather than floating inset inside
   blank card padding. gap:0 on the card for the same reason .nt-detail
   sets it: .auth-modal__card's base gap:14px would otherwise stack on top
   of the head/scroll's own padding, doubling the visual gap between them. */
.auth-modal__card.my-modal__card--wide { padding: 0; gap: 0; overflow: hidden; display: flex; flex-direction: column; }
.my-modal__card--wide .auth-modal__head {
  flex-shrink: 0;
  /* Same tuned values as .nt-detail .auth-modal__head (giveaway.css) — top
     eased down there across two follow-up asks, bottom kept smaller than
     top since the border-bottom already marks the boundary and the
     scroll wrapper's own top padding adds more space right after it. */
  padding: 16px 20px 12px;
  background: var(--modal-bg);
  border-bottom: 1px solid var(--border);
}
.my-modal__card--wide .my-modal__scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 10px 20px 20px;
}

/* Groups a field/button with its directly-related hint text at a tighter gap
   than the modal card's default inter-section gap (14px) — keeps related
   items visually attached instead of every line reading as its own section. */
.my-modal-group { display: flex; flex-direction: column; gap: 6px; }
/* A class-based `display` always beats the UA [hidden] rule's specificity
   (same issue fixed for .auth-error) — without this, a hidden tab panel
   using this class stays visible, stacking on top of the active tab. */
.my-modal-group[hidden] { display: none; }

/* Forced X-handle re-entry (2026-08-16) — shown only to an account whose
   handle was cleared because another member had OAuth-verified it. Colours
   come from the shared theme tokens (`--danger-text`, `--like-red-rgb`), which
   are redefined per theme in tokens.css, so this stays readable in Light mode
   without a second rule. The matching red on the input itself is the existing
   `.auth-input.is-invalid`, reused rather than duplicated. */
.my-modal-alert {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 12px 14px;
  border-radius: var(--radius-lg);
  font-size: 13px;
  line-height: 1.55;
}
.my-modal-alert--danger {
  background: rgba(var(--like-red-rgb), 0.10);
  border: 1px solid rgba(var(--like-red-rgb), 0.45);
  color: var(--danger-text);
}
.my-modal-alert__icon { flex-shrink: 0; line-height: 1; }
.my-modal-alert__icon img { width: 18px; height: 18px; display: block; }
.my-modal-alert__text { display: flex; flex-direction: column; gap: 4px; }
.my-modal-alert__text strong { font-weight: 700; }
/* The instruction line reads as supporting copy under the headline, so it sits
   10% below the alert's own size (0.9em of 13px = 11.7px). `em`, not a fixed
   px value, so it keeps tracking if the alert's base size is ever changed. */
.my-modal-alert__desc { font-size: 0.9em; }
.auth-label--danger { color: var(--danger-text); }

/* Section header (Edit Profile "ข้อมูลส่วนตัว" tab) — separates the tab's
   fields into Account / About you / Privacy so unrelated field types (locked
   text, input+button, picker, chips, toggle) don't read as one long list. */
.my-modal-section {
  display: flex; flex-direction: column; gap: 14px;
  padding-top: 14px; border-top: 1px solid var(--border);
}
.my-modal-section:first-child { padding-top: 0; border-top: none; }
.my-modal-section__label {
  font-size: 11px; font-weight: 600; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--text-secondary);
}

/* Tab bar (Edit Profile) */
.my-tabbar {
  display: flex; gap: 6px;
  padding: 4px;
  background: rgba(var(--surface-rgb), 0.05);
  border-radius: var(--radius-xl);
}
.my-tabbar__btn {
  flex: 1;
  padding: 9px 6px;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-secondary);
  font: 600 12px var(--font-thai);
  cursor: pointer;
}
/* Phones (2026-10-22): 4 tabs no longer fit one row — 2 columns, wrapping. */
@media (max-width: 480px) {
  .my-tabbar { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.my-tabbar__btn.is-active {
  background: rgba(var(--accent-gold-rgb), 0.14);
  border-color: var(--accent-gold);
  color: var(--accent-gold-text);
}

/* Toggle switch (Privacy Mode / Primary ticket) */
.my-toggle-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 14px;
  background: rgba(var(--surface-rgb), 0.05);
  border: 1px solid rgba(var(--surface-rgb), 0.1);
  border-radius: var(--radius-lg);
}
.my-toggle-row--gold { border-color: rgba(var(--accent-gold-rgb), 0.5); }
.my-toggle-row__txt { display: flex; flex-direction: column; gap: 2px; }
.my-toggle-row__title { font-size: 12px; font-weight: 600; }
.my-toggle-row__desc { font-size: 10px; color: var(--text-secondary); }
.my-switch {
  position: relative; flex-shrink: 0;
  width: 40px; height: 22px;
  border: none; border-radius: var(--radius-lg);
  /* Track only — the knob (.my-switch::after) stays literal white in both
     themes, same as a native iOS switch's knob. */
  background: rgba(var(--surface-rgb), 0.15);
  cursor: pointer;
}
.my-switch::after {
  content: ''; position: absolute; top: 2px; left: 2px;
  /* Knob follows the track's corner (2026-10-23) — see .adm-switch::after. */
  width: 18px; height: 18px; border-radius: max(0px, calc(var(--radius-lg) - 2px));
  background: var(--white); transition: left 0.15s ease;
}
.my-switch.is-on { background: var(--accent-gold); }
:root[data-theme="light"] .my-switch.is-on { background: var(--brand-gold); }
.my-switch.is-on::after { left: 20px; }

/* Avatar preview row (Emoji tab) */
.my-modal-preview {
  display: flex; align-items: center; gap: 10px;
}
.my-modal-preview__avatar {
  width: 48px; height: 48px;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-full);
  border: 3px solid var(--accent-teal);
  background: var(--bg-elevated);
  font-size: 20px;
}
.my-modal-preview__txt { display: flex; flex-direction: column; gap: 2px; }
.my-modal-preview__title { font-size: 12px; font-weight: 600; }
.my-modal-preview__sub { font-size: 10px; color: var(--text-secondary); }

/* Select fields */
.my-select {
  width: 100%; min-width: 0;
  height: 44px; padding: 0 12px;
  background: var(--bg-primary);
  border: 1px solid rgba(var(--surface-rgb), 0.1);
  border-radius: var(--radius-lg);
  color: var(--text-primary);
  font: 400 13px var(--font-thai);
}
/* Open option list is native/OS-rendered, ignores the closed box's theming
   above — see CLAUDE.md "Native <select> dropdown theming". */
.my-select option { background: var(--bg-elevated); color: var(--text-primary); }
/* min-width:0 lets flex children shrink below their content size — without
   it a <select> with a long option (e.g. a zone name) can overflow past the
   modal's edge instead of wrapping/ellipsis-ing inside its own column. */
.my-inline-field { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }

.my-field-row { display: flex; gap: 10px; }
.my-field-row .auth-field { flex: 1; min-width: 0; }
.my-field-row .auth-field .my-select,
.my-field-row .auth-field .auth-input { width: 100%; min-width: 0; }

/* Required current-password field (gold-tinted priority border) */
.auth-input--required { border-color: rgba(var(--accent-gold-rgb), 0.5); }
.auth-label__req { color: var(--danger-text); }

/* Gold info banner */
.my-modal-banner {
  padding: 10px 12px;
  border-radius: var(--radius-lg);
  background: rgba(var(--accent-gold-rgb), 0.12);
  color: var(--accent-gold-text);
  font-size: 11px; font-weight: 600;
}
.my-modal-banner--teal { background: rgba(var(--accent-teal-rgb), 0.12); color: var(--accent-teal-text); }

/* Teal link (masking example) */
.my-modal-link {
  background: none; border: none; padding: 0;
  color: var(--accent-teal);
  font: 600 11px var(--font-thai);
  cursor: pointer; text-align: left;
}
/* Masking example popup (2026-10-21) — desktop: four equal panels, each a
   fixed-height frame with the image centred (contain), title on top.
   <=768px: title tabs + one frame per swipe page, same frame height for all.
   View-only: no select, drag, long-press save or pinch zoom. */
.auth-modal__card.verify-ex-card { max-width: 1040px; width: calc(100% - 32px); }
.verify-ex__tabs { display: none; }
.verify-ex__track {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px;
  touch-action: pan-x;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}
.verify-ex__item { min-width: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.verify-ex__cap {
  font: 600 12px var(--font-thai); color: var(--text-primary);
  text-align: center; padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}
.verify-ex__frame {
  height: 340px; padding: 10px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: rgba(var(--surface-rgb), 0.04);
}
.verify-ex__img {
  display: block; max-width: 100%; max-height: 100%;
  border-radius: var(--radius-md);
  pointer-events: none;
  -webkit-user-drag: none;
}
@media (max-width: 768px) {
  .verify-ex__tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-bottom: 10px; }
  .verify-ex__tab {
    padding: 8px 6px;
    border: 1px solid var(--border); border-radius: var(--radius-lg);
    background: none; color: var(--text-secondary);
    font: 600 11px var(--font-thai); cursor: pointer;
  }
  .verify-ex__tab.is-active { border-color: var(--accent-teal); color: var(--accent-teal); }
  .verify-ex__track {
    display: flex; gap: 0;
    overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
  }
  .verify-ex__track::-webkit-scrollbar { display: none; }
  .verify-ex__item { flex: 0 0 100%; scroll-snap-align: start; }
  .verify-ex__cap { display: none; }
  .verify-ex__frame { height: min(46vh, 330px); }
}

/* Verify example frame: magnifier + tap opens the viewer (2026-10-22). */
.verify-ex__frame { position: relative; cursor: zoom-in; }
.verify-ex__zoom {
  position: absolute; right: 8px; bottom: 8px;
  width: 30px; height: 30px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border);
  background: var(--bg-primary); color: var(--text-primary);
  font-size: 13px; cursor: pointer;
}
/* View-only lightbox above the example popup. */
.verify-lb {
  position: fixed; inset: 0; z-index: 10000;
  display: flex; align-items: center; justify-content: center;
  padding: 56px 16px;
  background: rgba(0, 0, 0, 0.88);
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
  touch-action: pan-y;
}
.verify-lb__box { display: flex; flex-direction: column; align-items: center; gap: 10px; max-width: 100%; }
.verify-lb__img {
  display: block;
  max-width: min(600px, calc(100vw - 32px));
  max-height: min(600px, calc(100vh - 150px));
  width: auto; height: auto;
  border-radius: var(--radius-lg);
  pointer-events: none;
  -webkit-user-drag: none;
}
.verify-lb__cap { font: 600 13px var(--font-thai); color: #fff; text-align: center; }
.verify-lb__btn {
  position: absolute;
  width: 40px; height: 40px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid rgba(255, 255, 255, 0.25);
  background: rgba(0, 0, 0, 0.5); color: #fff;
  font-size: 16px; cursor: pointer;
}
.verify-lb__btn:disabled { opacity: 0.3; cursor: default; }
.verify-lb__close { top: calc(12px + var(--safe-top, 0px)); right: 12px; }
.verify-lb__prev { left: 12px; top: 50%; transform: translateY(-50%); }
.verify-lb__next { right: 12px; top: 50%; transform: translateY(-50%); }
@media (max-width: 768px) {
  .verify-lb__prev, .verify-lb__next { top: auto; bottom: calc(14px + var(--safe-bottom, 0px)); transform: none; }
  .verify-lb__prev { left: calc(50% - 52px); }
  .verify-lb__next { right: calc(50% - 52px); }
}

/* Upload dropzone */
.my-dropzone {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 22px 12px;
  border: 1px dashed rgba(var(--surface-rgb), 0.2);
  border-radius: var(--radius-xl);
  color: var(--text-secondary);
  font-size: 11px; text-align: center;
  cursor: pointer;
}
.my-dropzone.has-file { border-color: var(--accent-teal); color: var(--text-primary); }
.my-dropzone__icon { font-size: 22px; }
.my-dropzone__preview {
  max-width: 140px; max-height: 100px;
  border-radius: var(--radius-md);
  object-fit: cover;
}

/* Edit Ticket header status badge reuses .my-badge from my.css */
.my-modal-head-badges { display: flex; align-items: center; gap: 8px; }

/* List for Sale settings — receiving method (chips) + price (compact radio) */
.sale-chip-list { display: flex; flex-wrap: wrap; gap: 6px; }
.sale-chip {
  padding: 7px 12px;
  background: rgba(var(--surface-rgb), 0.05);
  border: 1px solid rgba(var(--surface-rgb), 0.15);
  border-radius: var(--radius-pill);
  color: var(--text-primary);
  font: 600 11px var(--font-thai);
  cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.sale-chip.is-selected { border-color: var(--accent-teal); background: rgba(var(--accent-teal-rgb), 0.14); color: var(--accent-teal-text); }

.sale-radio-list { display: flex; flex-direction: column; gap: 6px; }
.sale-radio-row {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px;
  background: rgba(var(--surface-rgb), 0.05);
  border: 1px solid rgba(var(--surface-rgb), 0.1);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.sale-radio-row input { width: 14px; height: 14px; accent-color: var(--accent-gold); cursor: pointer; flex-shrink: 0; }
.sale-radio-row__txt { flex: 1; font-size: 11px; }
.sale-radio-row__price { font-size: 12px; font-weight: 700; color: var(--accent-gold-text); white-space: nowrap; }
.sale-radio-row.is-selected { border-color: var(--accent-gold); background: rgba(var(--accent-gold-rgb), 0.1); }

/* Force New Password — blocking (no close button) */
.auth-modal--blocking .auth-modal__close { display: none; }

/* Health Status Check-In popup + edit selector (openHealthCheckinPopup,
   modals.js) — 4 status rows + a lower-emphasis skip row (§3.2). */
.health-option-list { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
.health-option-row {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px;
  background: rgba(var(--surface-rgb), 0.05);
  border: 1px solid rgba(var(--surface-rgb), 0.12);
  border-radius: var(--radius-lg);
  color: var(--text-primary);
  font: 600 13px var(--font-thai);
  cursor: pointer;
  text-align: left;
  transition: border-color 0.12s ease, background 0.12s ease, opacity 0.12s ease;
}
@media (hover: hover) { .health-option-row:hover { border-color: var(--accent-gold); } }
.health-option-row:disabled { opacity: 0.5; cursor: default; }
.health-option-row__icon { font-size: 18px; flex-shrink: 0; }
.health-skip-row {
  /* No margin-top here (2026-07-26 fix) — .auth-modal__card is already a
     flex column with gap: 14px between every child, so this used to stack
     an extra 12px on top of that gap and left too much space above the
     skip row specifically, vs. every other gap in the card. */
  display: block; width: 100%;
  padding: 10px 0;
  background: none; border: none;
  color: var(--text-secondary);
  font: 500 12px var(--font-thai);
  text-decoration: underline;
  cursor: pointer;
  text-align: center;
}
.health-skip-row:disabled { opacity: 0.5; cursor: default; }
/* Consent notice (2026-07-26 ask) — moved to the very bottom, merged with
   the "change anytime at myJASPER" note into one block. Kept as a plain
   caption line (2026-07-26 follow-up: an earlier pass made this a tinted
   frosted-glass block, but that read as too prominent for what's really
   just informational fine print — the emphasis treatment was meant for the
   toast instead, see toast.js). No margin — both the popup card
   (.auth-modal__card) and the banner's own flex parent already apply a gap
   between children, so an extra margin here double-spaced it. Also used by
   my.js's banner (outside its own card) — my/index.html already links this
   stylesheet, so no duplicate rule needed there. */
.health-notice {
  color: var(--text-secondary);
  font-size: 10.35px;
  line-height: 1.6;
  text-align: center;
}

/* Verify-ticket OCR status line (2026-10-21, openVerifyTicket). Only ever a
   hint — never blocks submit. Warn colour = the pending badge's (my.css). */
.verify-ocr { font-size: 12px; line-height: 1.5; color: var(--text-secondary); }
.verify-ocr--ok { color: var(--success-text); }
.verify-ocr--warn { color: #FABF59; }
:root[data-theme="light"] .verify-ocr--warn { color: #9F6605; }

/* "มีอะไรให้ช่วยดูแลไหม?" popup (openAssistNeedsPopup, modals.js) — 3 steps:
   category picker (circle icons, multi-select) → severity stepper (one
   screen per selected category) → review + note + consent. */
.assist-popup-body { display: flex; flex-direction: column; gap: 14px; }
.assist-hint { margin-top: -8px; font-size: 11.5px; color: var(--text-secondary); }
.assist-cat-row { display: flex; justify-content: space-between; gap: 6px; flex-wrap: wrap; }
.assist-cat-item {
  flex: 1; min-width: 64px;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  background: none; border: none; padding: 0;
  cursor: pointer;
}
.assist-cat-item__circle {
  position: relative;
  width: 52px; height: 52px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(var(--surface-rgb), 0.05);
  border: 1px solid rgba(var(--surface-rgb), 0.15);
  border-radius: var(--radius-full);
  font-size: 22px;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.assist-cat-item.is-selected .assist-cat-item__circle { border-color: var(--accent-gold); background: rgba(var(--accent-gold-rgb), 0.1); }
.assist-cat-item__check {
  position: absolute; bottom: -2px; right: -2px;
  width: 18px; height: 18px;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-gold);
  color: var(--bg-primary);
  border: 2px solid var(--bg-secondary);
  border-radius: var(--radius-full);
  font-size: 11px;
}
.assist-cat-item__label { font: 600 13px var(--font-thai); color: var(--text-primary); text-align: center; }
.assist-cat-item.is-selected .assist-cat-item__label { color: var(--accent-gold-text); }
.assist-cat-item__sublabel { font: 500 11px var(--font-thai); color: var(--text-secondary); margin-top: -2px; }

.assist-step-head { display: flex; align-items: center; gap: 8px; font: 700 15px var(--font-thai); }
.assist-progress { display: flex; gap: 4px; }
.assist-progress__bar { flex: 1; height: 3px; border-radius: var(--radius-xs); background: rgba(var(--surface-rgb), 0.15); }
.assist-progress__bar.is-active { background: var(--accent-gold); }
.assist-step-question { font-size: 13.5px; color: var(--text-secondary); }
.assist-severity-list { display: flex; flex-direction: column; gap: 8px; }
.assist-severity-row {
  padding: 12px;
  background: rgba(var(--surface-rgb), 0.05);
  border: 1px solid rgba(var(--surface-rgb), 0.12);
  border-radius: var(--radius-lg);
  color: var(--text-primary);
  font: 600 13px var(--font-thai);
  text-align: left;
  cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.assist-severity-row.is-selected { border-color: var(--accent-gold); background: rgba(var(--accent-gold-rgb), 0.06); }
@media (hover: hover) { .assist-severity-row:hover { border-color: var(--accent-gold); background: rgba(var(--accent-gold-rgb), 0.06); } }
.assist-step-nav { display: flex; gap: 8px; }
.assist-step-nav .auth-btn { flex: 1; }
.assist-popup-body .auth-btn--primary { display: flex; align-items: center; justify-content: center; gap: 6px; }
.assist-btn-arrow { display: inline-flex; font-size: 13px; }

.assist-review-list { display: flex; flex-direction: column; gap: 8px; }
.assist-review-row { display: flex; align-items: flex-start; gap: 10px; }
.assist-review-row__icon { font-size: 18px; flex-shrink: 0; margin-top: 1px; }
.assist-review-row__label { font: 700 13px var(--font-thai); }
.assist-review-row__severity { font-size: 12px; color: var(--text-secondary); }
.assist-note-input { min-height: 64px; resize: vertical; }

/* Admin-added health report popup (openHealthReportPopup, modals.js) */
.health-report__handle {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 10px;
  font: 700 14px var(--font-thai);
  color: var(--text-primary);
}
.health-report__handle svg { width: 16px; height: 16px; flex-shrink: 0; }

/* Generic confirm modal (openConfirmModal, modals.js) */
.auth-modal__actions { display: flex; gap: 10px; margin-top: 18px; }
.auth-modal__actions .auth-btn { width: auto; flex: 1; padding: 13px; }
.auth-btn--danger { background: var(--like-red); color: var(--white); padding: 15px; }
:root[data-theme="light"] .auth-btn--danger { background: var(--status-like); }

/* ── /p/my "ถึงบ้านหรือยัง" nudge (modals.js openHomeSafePopup(), 2026-08-21).
   Rides on showNoTicketModal's `.noticket-modal` layout (centered icon badge,
   title, sub, full-width gradient primary button) — only the round chip and
   the smaller stacked "not yet" button below the primary are new here.
   Lives in modals.css rather than beside `.noticket-modal` in auth.css
   because auth.css is cache-busted with ?v=N at every <link> site and this
   file is not — no reason to spend a sitewide bump on a rule one page
   renders. */
/* 10% smaller than the first pass (2026-08-21 follow-up ask) — every
   dimension scaled together, not just the type, so the pill keeps its
   proportions: 12px/4px/12px -> 10.8px/3.6px/10.8px. */
.homesafe-modal__round {
  font: 600 10.8px var(--font-thai);
  color: var(--text-secondary);
  background: rgba(var(--surface-rgb), 0.08);
  border: 1px solid rgba(var(--surface-rgb), 0.14);
  border-radius: var(--radius-pill);
  padding: 3.6px 10.8px;
  margin: -4px 0 2px;
}
.homesafe-modal__btn-icon { display: inline-flex; font-size: 17px; }
/* Lighter and shorter than the primary button above it (2026-08-21 ask:
   "ยังไม่ถึงเป็นปุ่มด้านล่าง เล็กกว่าถึงบ้าน") but the SAME WIDTH as it
   (2026-08-21 follow-up: "ความกว้างของทั้งสองปุ่มต้องเท่ากัน") — the first
   pass narrowed it to 58%, which was the wrong axis. `.auth-btn`'s base
   `width: 100%` already gives the match; the smaller reading comes from the
   type size and vertical padding alone. */
.homesafe-modal__later {
  width: 100%;
  padding: 10px 22px; font-size: 13px;
  margin-top: 2px;
}

/* Phase Control "module closed" card (2026-10-23) — shared by p/module-gate.js
   for Fan Forge, Sponsor Quest and Announcements. Same look as find.css's
   .find-disabled. modals.css is linked by every /p page that mounts the nav. */
.module-closed {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: 10px;
  max-width: 360px; margin: 0 auto; padding: 40px 24px;
  min-height: calc(100dvh - var(--navbar-total-h, 64px));
}
.module-closed__icon {
  width: 64px; height: 64px; border-radius: var(--radius-full);
  border: 2px solid var(--accent-gold); background: rgba(var(--accent-gold-rgb), 0.08);
  display: flex; align-items: center; justify-content: center; font-size: 26px;
}
.module-closed__title { font-size: 18px; font-weight: 700; }
.module-closed__subtext { font-size: 13px; color: var(--text-secondary); }
.module-closed__chip {
  margin-top: 6px; font-size: 11px; color: var(--text-secondary);
  border: 1px solid var(--border); border-radius: var(--radius-pill); padding: 4px 12px;
}
