/* ─────────────────────────────────────────────────────────────────────────────
   RequestJapan.com — "Cockpit" design system (chosen 2026-07-29, replaces Hinomaru).
   Dense B2B ops console: dark sidebar, cool-gray canvas, white bordered
   panels, compact data tables, vermillion accent. Light theme only.
   ───────────────────────────────────────────────────────────────────────── */

:root {
  color-scheme: light;

  --bg:      #f4f5f7;
  --panel:   #ffffff;
  --wash:    #fafbfc;
  --line:    #e3e6ea;
  --line-2:  #d3d7dd;

  --ink:     #1a1d21;
  --sub:     #5f6670;
  --faint:   #969ca6;

  --side:      #15171b;
  --side-ink:  #c9ccd2;
  --side-mut:  #7a7f88;
  --side-hov:  #23262c;

  --red:      #d8442e;
  --red-deep: #b7331f;
  --red-soft: #fcebe4;
  --red-line: #f2c4b8;

  --ok-ink:  #177245; --ok-soft:  #e4f2ea; --ok-line: #bfdccc;
  --info-ink:#33527a; --info-soft:#e8eef6; --info-line:#c4d2e4;

  --r: 9px;
  --font: "Inter", -apple-system, BlinkMacSystemFont, "Hiragino Sans", "Noto Sans JP", sans-serif;
  /* The wordmark is a mark, not body copy. Surfaces may change --font; this
     one is pinned so the logo is the same object on every page. */
  --font-brand: "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  --brand-ink:  #1a1d21;
}

* { box-sizing: border-box; }
body { margin: 0; font-family: var(--font); color: var(--ink); background: var(--bg);
       font-size: 13.5px; line-height: 1.55; -webkit-font-smoothing: antialiased; }
a { color: inherit; text-decoration: none; }
a:hover { color: var(--red); }
h1 { font-weight: 800; font-size: 1.35rem; line-height: 1.25; letter-spacing: -.01em; margin: 0; }
h2 { font-weight: 800; font-size: 1.1rem; letter-spacing: -.01em; }
h3 { font-size: .7rem; font-weight: 700; margin: 0 0 .9rem; text-transform: uppercase;
     letter-spacing: .12em; color: var(--sub); }
code { font-size: .82em; background: var(--bg); padding: .12em .4em; border-radius: 5px; color: var(--sub); }

.kicker { color: var(--red); font-size: .68rem; font-weight: 700; letter-spacing: .16em;
          text-transform: uppercase; margin-bottom: .5rem; }

/* ── Brand ─────────────────────────────────────────────────────────────── */
/* Pinned, not inherited: font, weight, tracking and ink are all fixed so the
   mark is byte-identical on the Mercari-flat JP surface and the collector one.
   .sidebar .brandmark is more specific and still turns it white. */
.brandmark { display: inline-flex; align-items: center; gap: .5rem;
             font-family: var(--font-brand); font-weight: 800; font-size: 1rem;
             letter-spacing: -.02em; color: var(--brand-ink) !important; }
.brandmark .dot { width: 18px; height: 18px; border-radius: 50%; background: var(--red); flex-shrink: 0; }
.brandmark.brand-lg { font-size: 1.5rem; }
.brandmark.brand-lg .dot { width: 28px; height: 28px; }
.env-tag { font-size: .58rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
           color: #fff; background: var(--red); padding: .14rem .5rem;
           border-radius: 4px; margin-left: .6rem; }

/* ── App shell: dark sidebar + main column ─────────────────────────────── */
.shell { display: grid; grid-template-columns: 216px minmax(0, 1fr); min-height: 100vh;
         /* The sidebar is sticky + 100vh, so on a page taller than the viewport its
            column would show bare canvas below it. Paint the column on the grid. */
         background: linear-gradient(to right, var(--side) 0 216px, transparent 216px); }
.sidebar { background: var(--side); color: var(--side-ink); padding: 1rem .8rem;
           display: flex; flex-direction: column; position: sticky; top: 0;
           height: 100vh; overflow-y: auto; }
.sidebar .brandmark { color: #fff !important; padding: .3rem .5rem 1rem; flex-wrap: wrap;
                      row-gap: .35rem; font-size: .95rem; }
.sidebar .env-tag { margin-left: .35rem; font-size: .52rem; padding: .1rem .38rem; }
.sidebar h5 { font-size: .6rem; letter-spacing: .14em; text-transform: uppercase;
              color: var(--side-mut); padding: .9rem .55rem .35rem; margin: 0; font-weight: 700; }
.nv { display: flex; align-items: center; gap: .55rem; padding: .45rem .6rem; border-radius: 7px;
      font-weight: 600; font-size: .84rem; margin-bottom: 2px; color: var(--side-ink); }
.nv:hover { background: var(--side-hov); color: #fff; }
.nv.on { background: var(--red); color: #fff; }
.nv .n { margin-left: auto; background: #2c2f36; border-radius: 99px; padding: .02rem .5rem;
         font-size: .68rem; font-weight: 700; }
.nv.on .n { background: rgba(255,255,255,.25); }
.sidebar .foot { margin-top: auto; font-size: .72rem; color: var(--side-mut);
                 padding: .8rem .55rem .2rem; border-top: 1px solid #24272d; }
.sidebar .foot b { color: var(--side-ink); display: block; font-size: .76rem; }
.sidebar .foot form { margin-top: .6rem; }
.sidebar .foot .lang-switch { margin-top: .7rem; }
.sidebar .foot .lang-switch form { margin-top: 0; }
.sidebar select { width: 100%; font: inherit; font-size: .76rem; color: var(--side-ink);
                  background: var(--side-hov); border: 1px solid #2c2f36; border-radius: 6px;
                  padding: .3rem .5rem; margin-bottom: .5rem; }

main.container { max-width: 1240px; margin: 0 auto; padding: 1.4rem 1.8rem 4rem; width: 100%; }
body.public main.container { max-width: 1080px; padding-top: 3rem; }

/* ── Page header (toolbar row) ─────────────────────────────────────────── */
.page-head { display: flex; align-items: center; justify-content: space-between;
             gap: 1.5rem; margin-bottom: 1.2rem; }
.page-head .sub { color: var(--sub); font-size: .85rem; margin: .3rem 0 0; }
/* Each button_to is its own <form> — a nested form is dropped by the browser,
   so they have to be siblings. Left to themselves they are block elements of
   different widths stacking unevenly; the row is what makes "publish" and
   "cancel" sit level. */
.page-head .actions { flex-shrink: 0; display: flex; align-items: stretch; gap: .5rem; }
.page-head .actions form { margin: 0; display: flex; }
.page-head .actions .btn { white-space: nowrap; }
.page-head .kicker { margin-bottom: .2rem; }

/* ── Panels ────────────────────────────────────────────────────────────── */
.card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
        padding: 1.4rem 1.6rem; margin-bottom: 1.1rem; }
.card h2 { margin-top: 0; }
.card-narrow { max-width: 640px; }
/* Detail pages that stack narrow cards: keep every block on the same measure,
   including wide children like the claim thread. */
.col-narrow { max-width: 640px; }
.col-narrow .card, .col-narrow .card-narrow { max-width: none; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1.2rem; align-items: start; }
@media (max-width: 780px) { .grid-2 { grid-template-columns: 1fr; } }

/* ── Data tables: boxed dense panels ───────────────────────────────────── */
table.list { width: 100%; border-collapse: separate; border-spacing: 0; background: var(--panel);
             border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
table.list th { text-align: left; font-size: .62rem; font-weight: 700; text-transform: uppercase;
                letter-spacing: .09em; color: var(--sub); padding: .55rem 1rem;
                background: var(--wash); border-bottom: 1px solid var(--line);
                white-space: nowrap; }
table.list td { padding: .7rem 1rem; border-bottom: 1px solid #eef0f3;
                vertical-align: middle; font-size: .84rem; }
table.list td:not(:first-child) { white-space: nowrap; }
table.list tr:last-child td { border-bottom: none; }
table.list tr:hover td { background: var(--wash); }
table.list td a { font-weight: 700; }
table.list th.num, table.list td.num { text-align: right; font-variant-numeric: tabular-nums; }
.cell-sub { display: block; color: var(--faint); font-size: .72rem; font-weight: 400; margin-top: .1rem; }
.card table.list { border: none; border-radius: 0; }
.card table.list td { padding: .6rem 1rem .6rem 0; }

/* thumbnails in lists */
.thumb { width: 38px; height: 38px; border-radius: 6px; flex-shrink: 0;
         display: flex; align-items: center; justify-content: center; }
.thumb svg { width: 17px; height: 17px; }
.rowflex { display: flex; align-items: center; gap: .8rem; }
.tint-0 { background: #efe9dc; color: #a08a5f; }
.tint-1 { background: #e6e0f0; color: #7a68a6; }
.tint-2 { background: #e0ebe4; color: #5d8a72; }
.tint-3 { background: #f2e0e0; color: #a66868; }
.thumb img { width: 100%; height: 100%; object-fit: cover; border-radius: 6px; }

/* ── Badges: compact status chips ──────────────────────────────────────── */
.badge { display: inline-block; padding: .13rem .5rem; border-radius: 5px;
         font-size: .66rem; font-weight: 700; letter-spacing: .03em; white-space: nowrap;
         background: #eef0f3; color: var(--sub); }
.badge-open, .badge-active, .badge-approved, .badge-escrowed, .badge-paid,
.badge-succeeded, .badge-fulfilled { background: var(--ok-soft); color: var(--ok-ink); }
.badge-exclusive, .badge-shortlisted, .badge-pending, .badge-awaiting_payment,
.badge-applied, .badge-draft, .badge-under_review, .badge-executing, .badge-batched,
.badge-requires_payment { background: var(--red-soft); color: var(--red-deep); }
.badge-shipped, .badge-delivered, .badge-awarded, .badge-accepted, .badge-closed,
.badge-processing, .badge-resolved_partial { background: var(--info-soft); color: var(--info-ink); }
.badge-cancelled, .badge-expired, .badge-rejected, .badge-suspended, .badge-declined,
.badge-lost, .badge-withdrawn, .badge-in_claim, .badge-held, .badge-failed,
.badge-refunded, .badge-resolved_refund { background: var(--red-soft); color: var(--red-deep);
                                          box-shadow: inset 0 0 0 1px var(--red-line); }

/* ── Buttons ───────────────────────────────────────────────────────────── */
/* A transparent border rather than none, so a filled button and an outlined
   one are the same height. Without it, "publish" (no border) and "cancel" (a
   1px one) sat a pixel apart wherever they appeared side by side, which is
   exactly the kind of thing that reads as sloppy without being nameable. */
.btn { display: inline-block; border: 1px solid transparent; cursor: pointer;
       font: inherit; font-weight: 700;
       font-size: .84rem; line-height: 1.25; padding: .55rem 1.1rem; border-radius: 7px;
       background: var(--red); color: #fff; transition: background .15s ease; }
.btn:hover { background: var(--red-deep); color: #fff; }
.btn-brand { background: var(--red); }
.btn-secondary { background: var(--panel); color: var(--ink); border: 1px solid var(--line-2); }
.btn-secondary:hover { background: var(--wash); color: var(--ink); border-color: var(--faint); }
.btn-danger { background: var(--panel); color: var(--red-deep); border: 1px solid var(--red-line); }
.btn-danger:hover { background: var(--red-soft); color: var(--red-deep); }
.btn-sm { padding: .35rem .8rem; font-size: .76rem; }

/* ── Forms ─────────────────────────────────────────────────────────────── */
form.stacked label { display: block; font-weight: 600; margin: 1rem 0 .3rem; font-size: .8rem; }
/* Every input except the ones that style themselves. This was a list of the
   types the forms happened to use, so the day a field changed from
   datetime-local to date it fell out of the list and rendered as raw browser
   chrome — a native box, a different height, a different font, beside eight
   fields that matched. Opting out is a short, closed list; opting in is not. */
form.stacked input:not([type=file]):not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=submit]):not([type=button]),
form.stacked textarea, form.stacked select {
  width: 100%; font: inherit; font-size: .86rem; color: var(--ink); background: var(--panel);
  border: 1px solid var(--line-2); border-radius: 7px; padding: .5rem .7rem; }
form.stacked input:focus, form.stacked textarea:focus, form.stacked select:focus {
  outline: 2px solid var(--red-line); border-color: var(--red); }
form.stacked input::placeholder, form.stacked textarea::placeholder { color: var(--faint); }
/* Block, not the inline-block a textarea defaults to. Inline-block sits on a
   text baseline and leaves descender space under it — a gap whose size is the
   browser's business, not ours. Anything placed under a textarea then needs a
   negative margin to look right, and that margin is correct in exactly one
   browser: on the others the thing below it lands on top of the field. */
form.stacked textarea { display: block; min-height: 90px; resize: vertical; }
/* A date input carries native chrome the rest of the form does not: its own
   picker button, and on some browsers its own idea of line height. Match the
   field height to the others and tint the button so it reads as ours. */
form.stacked input[type=date]::-webkit-calendar-picker-indicator {
  cursor: pointer; opacity: .55; transition: opacity .15s; }
form.stacked input[type=date]:hover::-webkit-calendar-picker-indicator { opacity: 1; }
form.stacked input[type=file] { width: 100%; font: inherit; font-size: .82rem; color: var(--sub);
  background: var(--panel); border: 1px dashed var(--line-2); border-radius: 7px; padding: .5rem .7rem; }
/* The whole .upload-zone is a <label>: clicking anywhere in it opens the
   picker, so the native control only adds untranslatable English chrome. */
form.stacked .upload-zone input[type=file] { position: absolute; width: 1px; height: 1px;
                                             opacity: 0; pointer-events: none; }
form.stacked input[type=file]::file-selector-button {
  font: inherit; font-size: .78rem; font-weight: 600; color: var(--ink); background: var(--bg);
  border: 1px solid var(--line-2); border-radius: 5px; padding: .28rem .7rem; margin-right: .7rem;
  cursor: pointer; }
form.stacked input[type=file]:hover::file-selector-button { border-color: var(--red); color: var(--red); }
form.stacked hr { border: none; border-top: 1px solid var(--line); margin: 1.5rem 0 .4rem; }
form.stacked .hint { color: var(--faint); font-size: .74rem; margin-top: .3rem; }
form.stacked .grid-2 { gap: 0 1.2rem; }
form.stacked .grid-2 > div > label:first-child { margin-top: 1rem; }
.grid-2 .span-2 { grid-column: 1 / -1; }

/* ── Flash ─────────────────────────────────────────────────────────────── */
.flash { padding: .7rem 1.1rem; border-radius: 7px; margin-bottom: 1rem; font-size: .84rem;
         font-weight: 600; background: var(--ok-soft); color: var(--ok-ink);
         border: 1px solid var(--ok-line); }
.flash-alert { background: var(--red-soft); color: var(--red-deep); border-color: var(--red-line); }

/* ── KPI cards (stats) ─────────────────────────────────────────────────── */
.stats-bar { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
             gap: .9rem; margin-bottom: 1.2rem; }
.stats-bar .stat { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
                   padding: .8rem 1rem; }
.stats-bar .num { font-size: 1.5rem; font-weight: 800; line-height: 1.2;
                  font-variant-numeric: tabular-nums; }
.stats-bar .label { font-size: .64rem; font-weight: 700; text-transform: uppercase;
                    letter-spacing: .08em; color: var(--sub); margin-top: .05rem; }
.stats-bar .sub-metric { font-size: .72rem; color: var(--faint); margin-top: .3rem; }

/* ── Content + right rail ──────────────────────────────────────────────── */
.rail-layout { display: grid; grid-template-columns: minmax(0, 1fr) 272px; gap: 1.2rem;
               align-items: start; }
@media (max-width: 1080px) { .rail-layout { grid-template-columns: 1fr; } }
.rail .panel { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
               margin-bottom: 1rem; overflow: hidden; }
.rail .panel-head { display: flex; align-items: center; justify-content: space-between;
                    padding: .65rem 1rem; border-bottom: 1px solid var(--line); }
.rail .panel-head b { font-size: .8rem; }
.rail .panel-head span { font-size: .68rem; color: var(--sub); }
.rail .row { display: flex; gap: .6rem; padding: .6rem 1rem; border-bottom: 1px solid #eef0f3;
             font-size: .74rem; align-items: flex-start; }
.rail .row:last-child { border-bottom: none; }
.rail .row .dot2 { width: 8px; height: 8px; border-radius: 50%; margin-top: .35rem;
                   flex-shrink: 0; background: var(--red); }
.rail .row .dot2.g { background: var(--ok-ink); } .rail .row .dot2.b { background: var(--info-ink); }
.rail .row b { font-size: .76rem; display: block; }
.rail .row .tm { color: var(--faint); font-size: .66rem; margin-left: auto; white-space: nowrap; }
.rail .mrow { display: flex; justify-content: space-between; padding: .5rem 1rem;
              border-bottom: 1px solid #eef0f3; font-size: .78rem; }
.rail .mrow:last-child { border-bottom: none; }
.rail .mrow b { font-variant-numeric: tabular-nums; }

/* ── Auth pages ────────────────────────────────────────────────────────── */
/* Centred with auto margins rather than justify-content: a form taller than
   the phone (registration is) would otherwise have its top pushed above the
   viewport, where scrolling cannot reach it. dvh because iOS counts the URL
   bar in vh, which cuts the last field off until you scroll the bar away. */
body.auth { display: flex; flex-direction: column; align-items: center;
            justify-content: flex-start; min-height: 100vh; min-height: 100dvh;
            padding: 2rem 1rem; box-sizing: border-box; gap: 1.1rem; }
.auth-card { margin-top: auto; }
.auth-langs { display: flex; justify-content: center; margin-bottom: auto; }
/* min(), not a fixed width. At 384px flat the card was wider than the space
   left by the body's padding on a 390px phone and wider than the phone itself
   below that — and because the column is centred, the overflow went to both
   sides, putting the left edge of every label at a negative x where no amount
   of scrolling reaches it. The register form, at an inline 520px, lost its
   whole left column that way. */
.auth-card { width: min(384px, 100%); box-sizing: border-box;
             background: var(--panel); border: 1px solid var(--line);
             border-radius: 12px; padding: 2.2rem 2.2rem 2rem;
             box-shadow: 0 8px 28px rgba(20,22,26,.07); }
.auth-card-wide { width: min(520px, 100%); }
.auth-card .brandmark { margin-bottom: 1.4rem; }
.auth-card h2 { font-size: 1.05rem; margin: 0 0 1rem; }
.auth-card-wide h2 { font-size: 1.35rem; letter-spacing: -.01em; margin-bottom: .5rem; }
.auth-card .btn { width: 100%; margin-top: 1.3rem; text-align: center; }
.auth-card .aux { margin-top: 1rem; font-size: .78rem; color: var(--sub); text-align: center; }
.auth-card .aux a { color: var(--red); font-weight: 600; }
.auth-card .card { border: none; padding: 0; margin: 0; background: transparent; }

/* ── Empty states ──────────────────────────────────────────────────────── */
.empty { text-align: center; color: var(--faint); padding: 3.2rem 1rem; font-size: .88rem;
         background: var(--panel); border: 1px dashed var(--line-2); border-radius: var(--r); }
.empty .dot-mark { display: inline-block; width: 12px; height: 12px; border-radius: 50%;
                   background: var(--red-line); margin-bottom: .6rem; }

code.wrap, .wrap-any { word-break: break-all; overflow-wrap: anywhere; }

/* Click-to-select fields (invitation links, TOTP URI). Styled like an input so
   they don't fall back to raw browser chrome inside a Cockpit panel. */
input.copy { width: 100%; font: inherit; font-size: .76rem; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
             color: var(--sub); background: var(--wash); border: 1px solid var(--line-2);
             border-radius: 6px; padding: .34rem .55rem; cursor: pointer; }
input.copy:focus { outline: 2px solid var(--red-line); border-color: var(--red); color: var(--ink); }

.rail .row-link { text-decoration: none; color: inherit; }
.rail .row-link:hover { background: var(--wash); }
.rail .dot2.r { background: var(--red); }

/* Segmented control: one compact affordance where two full buttons would
   overflow. Shares the language switcher's shape so the nav reads as a set. */
.seg { display: inline-flex; align-items: center; gap: 2px; padding: 2px;
       border-radius: 999px; background: var(--wash); border: 1px solid var(--line);
       white-space: nowrap; }
.seg-label { font-size: .68rem; font-weight: 700; text-transform: uppercase;
             letter-spacing: .06em; color: var(--faint); padding: 0 .5rem 0 .6rem; }
.l-nav .seg a, .legal-head .seg a {
  font-size: .78rem; font-weight: 700; color: var(--sub); background: var(--panel);
  border: 1px solid var(--line-2); border-radius: 999px; padding: .22rem .7rem;
  line-height: 1.5; }
.l-nav .seg a:hover, .legal-head .seg a:hover { color: var(--ink); border-color: var(--ink); }

/* ── Language switcher (every page) ────────────────────────────────────── */
.lang-switch { display: inline-flex; flex-wrap: nowrap; white-space: nowrap;
               gap: 2px; padding: 2px; border-radius: 999px;
               background: var(--wash); border: 1px solid var(--line); }
.lang-switch-form { display: inline; margin: 0; }
.lang-switch a, .lang-switch button { font: inherit; font-size: .7rem; font-weight: 700; letter-spacing: .02em;
                      color: var(--sub); background: transparent; border: none; cursor: pointer;
                      padding: .22rem .6rem; border-radius: 999px; line-height: 1.5; }
.lang-switch a:hover, .lang-switch button:hover { color: var(--ink); }
.lang-switch a.on, .lang-switch button.on { background: var(--panel); color: var(--ink);
                                             box-shadow: 0 1px 2px rgba(16, 18, 22, .08); }
.lang-switch a { display: inline-block; text-decoration: none; }

/* Inside the dark sidebar the same control inverts. */
.lang-switch-dark { background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .1);
                    width: 100%; justify-content: center; }
.lang-switch-dark a, .lang-switch-dark button { color: var(--side-mut); }
.lang-switch-dark a:hover, .lang-switch-dark button:hover { color: #fff; }
.lang-switch-dark a.on, .lang-switch-dark button.on { background: rgba(255, 255, 255, .14);
                                                      color: #fff; box-shadow: none; }

/* ── Filters, misc ─────────────────────────────────────────────────────── */
.filter-row { display: flex; gap: .4rem; flex-wrap: wrap; margin-bottom: 1.2rem; }
.filter-row a { font-size: .78rem; font-weight: 600; color: var(--sub); background: var(--panel);
                border: 1px solid var(--line); padding: .3rem .85rem; border-radius: 999px; }
.filter-row a.on, .filter-row a:hover { background: var(--ink); border-color: var(--ink); color: #fff; }
.muted { color: var(--faint); }
.hero { text-align: center; padding: 11vh 1rem 2.5rem; }
.hero .brandmark { margin-bottom: 1.4rem; }
.hero p.tagline { max-width: 460px; margin: 1rem auto 2rem; color: var(--sub); font-size: 1rem; }
.hero h1, h1.display { font-size: 2rem; font-weight: 800; }

/* ── Negotiation thread ────────────────────────────────────────────────── */
/* A <ul> that is a flex column is still a list: without this the negotiation
   bubbles each carried a marker floating beside them. */
.thread { display: flex; flex-direction: column; gap: .6rem; list-style: none; margin: 0; padding: 0; }
.thread .msg { max-width: 78%; padding: .65rem .9rem; border-radius: 9px; font-size: .84rem;
               background: var(--bg); border: 1px solid var(--line); }
.thread .msg.mine { align-self: flex-end; background: var(--red-soft); border-color: var(--red-line); }
.thread .msg .price { font-weight: 800; }
.thread .muted { margin-top: .12rem; font-size: .68rem; }

/* ── Deal showcase cards ───────────────────────────────────────────────── */
.deal-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 1rem; }
.deal-grid-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) { .deal-grid-4 { grid-template-columns: repeat(2, 1fr); } }
.deal-card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
             overflow: hidden; font-size: .82rem; }
.deal-card-img { position: relative; aspect-ratio: 4 / 3; display: flex; align-items: center;
                 justify-content: center; }
.deal-card-img img { width: 100%; height: 100%; object-fit: cover; position: absolute; inset: 0; }
.deal-card-img svg { width: 30px; height: 30px; opacity: .55; }
.deal-card-img .sold { position: absolute; top: .5rem; left: .5rem; background: var(--red);
                       color: #fff; font-size: .62rem; font-weight: 800; letter-spacing: .08em;
                       padding: .18rem .5rem; border-radius: 4px; }
.deal-card-title { font-weight: 700; padding: .7rem .9rem .1rem; line-height: 1.35; }
.deal-card-price { padding: .25rem .9rem 0; font-weight: 800; font-size: .95rem; }
.deal-card-price .muted { font-weight: 500; font-size: .74rem; }
.deal-card-meta { padding: .15rem .9rem .8rem; color: var(--faint); font-size: .7rem; }

/* ── Market prices (price-transparency pages) ──────────────────────────── */
.market-hero { text-align: center; padding: 2.8rem 1rem 2.2rem; background: var(--panel);
               border: 1px solid var(--line); border-radius: var(--r); }
.market-hero .big-price { font-size: 2.7rem; font-weight: 800; line-height: 1.05;
                          letter-spacing: -.02em; }
.market-hero .approx { color: var(--sub); font-size: 1rem; margin-top: .3rem; }
.market-hero .basis { color: var(--faint); font-size: .76rem; margin-top: .6rem; }

.price-band { max-width: 460px; margin: 1.6rem auto 0; }
.price-band .band-track { position: relative; height: 5px; background: #eef0f3; border-radius: 3px; }
.price-band .band-fill { position: absolute; top: 0; bottom: 0; background: var(--red-line);
  border-radius: 3px; }
.price-band .band-dot { position: absolute; top: 50%; width: 11px; height: 11px;
  background: var(--red); border-radius: 50%; transform: translate(-50%, -50%); }
.price-band .band-labels { display: flex; justify-content: space-between; margin-top: .5rem;
  font-size: .76rem; color: var(--sub); }
.price-band .band-labels b { color: var(--ink); font-weight: 700; }

.market-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1rem; }
@media (min-width: 900px) { .market-cards { grid-template-columns: repeat(3, 1fr); } }
.market-card { display: block; color: inherit; text-decoration: none; background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--r); padding: 1.2rem 1.3rem;
  transition: border-color .15s; }
.market-card:hover { border-color: var(--faint); }
.market-card .cat { font-size: .68rem; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--red); margin-bottom: .6rem; }
.market-card .avg { font-size: 1.55rem; font-weight: 800; line-height: 1.1; }
.market-card .approx { color: var(--sub); font-size: .82rem; margin-top: .1rem; }
.market-card .range { margin-top: .8rem; padding-top: .7rem; border-top: 1px solid var(--line);
  font-size: .76rem; color: var(--sub); display: flex; justify-content: space-between; }
.market-card .count { margin-top: .4rem; font-size: .7rem; color: var(--faint); }

.market-context { background: var(--wash); border: 1px solid var(--line); border-radius: var(--r);
  padding: 1rem 1.2rem; font-size: .82rem; margin: 1.4rem 0 .4rem; }
.market-context .mc-title { font-size: .64rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--red); margin-bottom: .4rem; }
.market-context .mc-price { font-size: 1.15rem; font-weight: 800; }
.market-context .mc-range { color: var(--sub); margin-top: .15rem; }
.market-context a { color: var(--red); text-decoration: none; font-weight: 600; }

/* ── Two-column form pages ─────────────────────────────────────────────── */
.form-layout { display: grid; grid-template-columns: minmax(0, 640px) minmax(260px, 1fr);
  gap: 1.4rem; align-items: start; }
@media (max-width: 980px) { .form-layout { grid-template-columns: 1fr; } }
.form-aside { position: sticky; top: 1.2rem; }
/* The four "how it works" boxes — new request, new offer, payment, new
   category. A stepper, not a bordered list: numbered chips joined by a rail,
   so the eye follows the sequence down the column instead of reading four
   equal-weight rows. The title was an inline <b> sitting flush against the
   body text; it is a block now, which is what the run-together line was. */
.how-it-works { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  padding: 1.2rem 1.4rem 1.3rem; }
.how-it-works ol { list-style: none; margin: 1rem 0 0; padding: 0; counter-reset: step; }
.how-it-works li { position: relative; counter-increment: step;
  padding: 0 0 1.15rem 2.4rem; }
.how-it-works li:last-child { padding-bottom: 0; }

/* The rail runs from under one chip to the next, and stops at the last. */
.how-it-works li::after { content: ""; position: absolute; left: 11px; top: 26px;
  bottom: 0; width: 1px; background: var(--line-2); }
.how-it-works li:last-child::after { display: none; }

.how-it-works li::before { content: counter(step); position: absolute; left: 0; top: 0;
  width: 23px; height: 23px; border-radius: 50%; box-sizing: border-box;
  background: var(--red-soft); border: 1px solid var(--red-line); color: var(--red-deep);
  font-size: .72rem; font-weight: 800; line-height: 1;
  display: flex; align-items: center; justify-content: center; }

.how-it-works li b { display: block; font-size: .85rem; font-weight: 700;
  line-height: 1.35; margin-bottom: .2rem; }
.how-it-works li span { display: block; color: var(--sub); font-size: .78rem; line-height: 1.55; }
body.jp .how-it-works li::before { border-radius: 4px; }

/* legacy helpers kept for public pages */
nav.topbar { display: flex; align-items: center; gap: 1.5rem; padding: 0 2rem; height: 58px;
             background: var(--panel); border-bottom: 1px solid var(--line);
             position: sticky; top: 0; z-index: 50; }
nav.topbar .brand-wrap { display: flex; align-items: center; margin-right: .6rem; }
nav.topbar a.nav-link { color: var(--sub); font-weight: 600; font-size: .86rem; padding: 1.15rem 0;
                        border-bottom: 2px solid transparent; }
nav.topbar a.nav-link:hover { color: var(--ink); }
nav.topbar a.nav-link.active { color: var(--ink); font-weight: 700; border-bottom-color: var(--red); }
nav.topbar .spacer { flex: 1; }
nav.topbar .who { font-size: .8rem; color: var(--sub); }
nav.topbar form { margin: 0; }
nav.topbar select { font: inherit; font-size: .8rem; color: var(--ink); background: var(--panel);
                    border: 1px solid var(--line-2); border-radius: 7px; padding: .3rem .7rem; }
.change-link { color: var(--red); font-size: .8rem; font-weight: 600; }

/* ── Company avatars (logo or tinted initial) ──────────────────────────── */
.avatar { border-radius: 6px; object-fit: cover; flex-shrink: 0; display: inline-flex;
          align-items: center; justify-content: center; vertical-align: middle; }
.avatar-fallback { font-weight: 800; }
.sidebar .avatar { border-radius: 5px; }

/* ── Key-value definition lists ────────────────────────────────────────── */
dl.kv { display: grid; grid-template-columns: minmax(120px, auto) 1fr; margin: 0; }
dl.kv dt { color: var(--sub); font-size: .8rem; padding: .42rem 1.2rem .42rem 0; }
dl.kv dd { margin: 0; padding: .42rem 0; font-size: .84rem; border-bottom: 1px solid #eef0f3; }
dl.kv dt { border-bottom: 1px solid #eef0f3; }
dl.kv dt:last-of-type, dl.kv dd:last-of-type { border-bottom: none; }
dl.kv dd.num { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
dl.kv dd > p:first-child { margin-top: 0; }
dl.kv dd > p:last-child { margin-bottom: 0; }
dl.kv .kv-total { font-weight: 800; font-size: .92rem; }

/* ── Photo grids on offers ─────────────────────────────────────────────── */
.photo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
              gap: .6rem; margin: .7rem 0; }
.photo-grid img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 7px;
                  border: 1px solid var(--line); }
.photo-grid-sm { grid-template-columns: repeat(auto-fill, minmax(74px, 1fr)); }

/* ── Misc components restored ──────────────────────────────────────────── */
.pill-row { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; margin: .3rem 0 .8rem; }

/* ── Card lookup ───────────────────────────────────────────────────────────
   Results under the card-name field, then the chosen card as a preview. The
   whole thing is an enhancement: it never covers the field it sits under and
   never blocks the form, so a slow catalogue costs a picture and nothing
   more. */
/* A remark, never an error. No red, no icon, no border — the form is fine
   whatever the catalogue says, and the styling should not suggest otherwise. */
/* ── "Improve with AI" ─────────────────────────────────────────────────────
   Sits under the description as a quiet secondary action, not a call to
   action: the buyer's own words are the default and this is an offer to
   tidy them. The rewritten fields flash once so it is obvious what moved. */
.polish-row { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem .7rem;
              margin: .55rem 0 .2rem; }
.btn-polish { flex: 0 0 auto; padding: .4rem .8rem; font: inherit; font-size: .78rem;
              font-weight: 600; color: var(--ink); background: #fff; cursor: pointer;
              border: 1px solid var(--line); border-radius: 999px;
              transition: border-color .15s, color .15s, background .15s; }
.btn-polish::before { content: "\2726"; margin-right: .4rem; color: var(--red); }
.btn-polish:hover:not(:disabled) { border-color: var(--red-line); color: var(--red); }
.btn-polish:disabled { opacity: .6; cursor: progress; }
.polish-note { flex: 1 1 15rem; min-width: 0; font-size: .72rem; line-height: 1.45;
               color: var(--sub); }
.polish-status { flex: 1 1 100%; font-size: .74rem; color: var(--red); }
.polish-status[hidden] { display: none; }
@keyframes polish-flash {
  from { background: rgba(216, 68, 46, .12); border-color: var(--red-line); }
  to   { background: #fff; }
}
.is-polished { animation: polish-flash 1.1s ease-out; }
@media (prefers-reduced-motion: reduce) { .is-polished { animation: none; } }

/* The catalogue is Pokémon-only, and a lot is not one card. When the lookup
   cannot run, the sentence telling you to "start typing and pick the exact
   card" is promising a picker that will never appear. */
.lookup-off .card-lookup-hint { display: none; }

.card-status { margin: .5rem 0 0; font-size: .76rem; color: var(--sub); line-height: 1.45; }
.card-status[hidden] { display: none; }

.card-count { margin: .5rem 0 0; font-size: .7rem; font-weight: 700; color: var(--faint);
              text-transform: uppercase; letter-spacing: .05em; }
.card-count[hidden] { display: none; }

/* "Pikachu" is two hundred cards. They are all here, in a panel that scrolls
   rather than one that pushes the rest of the form off the screen. */
.card-results { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
                gap: .5rem; margin-top: .5rem; max-height: 340px; overflow-y: auto;
                overscroll-behavior: contain; padding-right: .2rem; }
.card-results:empty { display: none; }
.card-hit { display: flex; flex-direction: column; gap: .2rem; padding: .4rem;
            background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
            cursor: pointer; text-align: left; font: inherit; color: var(--ink);
            transition: border-color .14s ease, transform .14s ease; }
.card-hit:hover { border-color: var(--red-line); transform: translateY(-2px); }
.card-hit img, .card-hit-blank { width: 100%; aspect-ratio: 63 / 88; border-radius: 5px;
                                 object-fit: cover; background: var(--wash); display: block; }
.card-hit-name { font-size: .72rem; font-weight: 700; line-height: 1.25;
                 overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card-hit-meta { font-size: .62rem; color: var(--faint); text-transform: uppercase;
                 letter-spacing: .04em; }

/* Twelve at a time, so the results do not bury the form. The button carries
   its own state: more to reveal, or a plain statement that the catalogue has
   more than we fetched — never a list that just stops. */
.card-more { display: block; width: 100%; margin-top: .5rem; padding: .55rem;
             background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
             font: inherit; font-size: .78rem; font-weight: 700; color: var(--red);
             cursor: pointer; transition: border-color .14s ease; }
.card-more:hover { border-color: var(--red-line); }
.card-more[hidden] { display: none; }
.card-more-done, .card-more-done:hover { color: var(--faint); font-weight: 600;
                                         cursor: default; border-color: var(--line); }

/* Twelve fits without scrolling; the cap only matters once you ask for more. */
.card-results { max-height: 420px; }

/* Results on the left, the enlargement in a column of its own on the right.
   Reserved rather than floating: a panel that appears over the list covers
   the cards you are trying to compare, and jumps as you move between them. */
.card-browse { display: flex; gap: .7rem; align-items: flex-start; margin-top: .5rem; }
.card-browse[hidden] { display: none; }
.card-browse .card-results { flex: 1 1 auto; min-width: 0; margin-top: 0; }

.card-zoom { flex: 0 0 168px; width: 168px; position: sticky; top: .25rem;
             background: var(--wash); border: 1px solid var(--line); border-radius: 10px;
             padding: .5rem; }
.card-zoom-hint { margin: 0; padding: 1.4rem .4rem; font-size: .7rem; line-height: 1.5;
                  color: var(--faint); text-align: center; }

/* The frame holds its shape before the scan arrives, so nothing jumps when
   it does — a card is 63×88mm and the panel is that ratio from the start. */
.card-zoom-frame { position: relative; display: block; width: 100%; aspect-ratio: 63 / 88;
                   border-radius: 6px; overflow: hidden; background: var(--panel);
                   border: 1px solid var(--line); }
.card-zoom-frame img { display: block; width: 100%; height: 100%; object-fit: cover;
                       opacity: 1; transition: opacity .18s ease; }
.card-zoom-frame img.is-loading { opacity: 0; }
.card-zoom-frame.is-ready .card-zoom-spinner { display: none; }

.card-zoom-spinner { position: absolute; inset: 0; margin: auto; width: 22px; height: 22px;
                     border: 2px solid var(--line-2); border-top-color: var(--red);
                     border-radius: 50%; animation: card-zoom-spin .7s linear infinite; }
@keyframes card-zoom-spin { to { transform: rotate(360deg); } }

/* It never arrived — a dead link, a slow CDN, an office firewall. Say so in
   the space rather than leaving a grey rectangle or a spinner that never
   stops. */
.card-zoom-frame.is-missing::after {
  content: "—"; position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: center; color: var(--faint); font-size: 1.4rem; }
.card-zoom-frame.is-missing .card-zoom-spinner { display: none; }

.card-zoom-name { display: block; margin-top: .4rem; font-size: .72rem; font-weight: 700;
                  text-align: center; color: var(--ink); line-height: 1.3;
                  overflow: hidden; text-overflow: ellipsis; }

.card-preview { display: flex; gap: .9rem; margin-top: .7rem; padding: .8rem;
                background: var(--wash); border: 1px solid var(--line); border-radius: var(--r); }
.card-preview[hidden] { display: none; }
.card-preview img { width: 84px; border-radius: 6px; align-self: flex-start;
                    box-shadow: 0 6px 16px -8px rgba(20, 22, 26, .5); }
.card-preview-body { display: flex; flex-direction: column; gap: .25rem; align-items: flex-start; }
.card-preview-body > b { font-size: .92rem; }
.card-preview-body > span { font-size: .76rem; color: var(--sub); }
.card-preview-price { font-size: .8rem; font-weight: 700; color: var(--ink); }
/* Somebody else's number, and it says so. */
.card-preview-price span { font-weight: 600; font-size: .66rem; color: var(--faint);
                           text-transform: uppercase; letter-spacing: .05em; margin-left: .3rem; }
.card-preview-body .btn { margin-top: .3rem; }

/* A field the schema does not apply to this request type is gone, not greyed. */
[data-spec-fields-target="field"][hidden] { display: none; }

/* ── Category picker ───────────────────────────────────────────────────────
   The first decision in the request flow. It used to be three grey buttons on
   an otherwise empty page, which read as a placeholder — so it is the page
   now: what each category is, drawn, and what it is closing at. The artwork
   is SVG on purpose (see CategoryArtHelper): a photograph of a card is
   somebody else's property, and these tiles sit in front of the shops that
   trade in it. */
.picker-lead { color: var(--sub); font-size: .95rem; max-width: 56ch; margin: -.4rem 0 1.4rem; }

/* The second picker keeps the breadcrumb on the same line as the question,
   so the step you are on and the step you came from read together. */
.picker-back { display: block; margin-top: .45rem; font-size: .82rem; color: var(--faint); }
.picker-back strong { color: var(--sub); font-weight: 700; }

.cat-picker { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
              gap: 1.1rem; align-items: stretch; }
@media (max-width: 1000px) { .cat-picker { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 700px)  { .cat-picker { grid-template-columns: minmax(0, 1fr); } }

.cat-card { display: flex; flex-direction: column; overflow: hidden;
            background: var(--panel); border: 1px solid var(--line);
            border-radius: var(--r); text-decoration: none; color: var(--ink);
            transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease; }
.cat-card:hover { transform: translateY(-3px); border-color: var(--red-line);
                  box-shadow: 0 14px 30px -14px rgba(20, 22, 26, .28); color: var(--ink); }
.cat-card:focus-visible { outline: 2px solid var(--red); outline-offset: 3px; }

.cat-art { display: block; position: relative; overflow: hidden; border-bottom: 1px solid var(--line); }
.cat-art img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }
/* The foil sweep the collector layer uses elsewhere, on hover only. */
.cat-art::after { content: ""; position: absolute; inset: 0; opacity: 0;
                  background: linear-gradient(105deg, transparent 35%, rgba(255,255,255,.55) 50%, transparent 65%);
                  transition: opacity .2s ease, transform .5s ease; transform: translateX(-30%); }
.cat-card:hover .cat-art::after { opacity: 1; transform: translateX(30%); }

.cat-body { display: flex; flex-direction: column; gap: .3rem; padding: 1rem 1.1rem 1.1rem; flex: 1; }
.cat-body > b { font-size: 1.02rem; font-weight: 800; letter-spacing: -.01em; }
.cat-blurb { color: var(--sub); font-size: .8rem; line-height: 1.5; }
.cat-go { margin-top: auto; padding-top: .9rem; border-top: 1px solid var(--line);
          font-size: .78rem; font-weight: 700; color: var(--red); }
.cat-go::after { content: " →"; transition: margin-left .16s ease; }
.cat-card:hover .cat-go::after { margin-left: .2rem; }

/* Flat surface, no lift, no sweep. */
body.jp .cat-card { border-radius: 4px; }
body.jp .cat-card:hover { transform: none; box-shadow: none; }
body.jp .cat-art::after { display: none; }

/* A one-line form inside a table cell: evidence note + button on one row. */
.inline-declare { display: flex; gap: .4rem; justify-content: flex-end; margin: 0; }
.inline-declare input { width: min(220px, 100%); }
.inline-declare .btn { white-space: nowrap; }
.showcase-strip { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
                  padding: 1.1rem 1.3rem 1.3rem; margin-bottom: 1.2rem; }
.showcase-strip h3 { margin-bottom: .9rem; }
.accent-bar { height: 3px; background: var(--red); border-radius: 2px; width: 34px;
              margin-bottom: 1rem; }
.auth-head-center { text-align: left; }
.upload-zone { border: 1px dashed var(--line-2); border-radius: 7px; padding: .8rem 1rem;
               background: var(--wash); font-size: .8rem; color: var(--sub); }

/* ── Public landing ────────────────────────────────────────────────────── */
/* The public pages are edge-to-edge: the coloured bands (nav, hero, alternate
   sections, footer) must reach the viewport edge, not stop at the app shell's
   1240px column. The negative margins below only cancel the container's own
   padding — on a screen wider than the container they would still leave a
   white gutter, so the container itself is unconstrained on these pages. */
main.container:has(> .landing),
main.container:has(> .legal-page) { max-width: none; padding: 0; }
main.container:has(> .landing) > .landing { margin: 0; }
main.container:has(> .legal-page) > .legal-page { margin: 0; min-height: 100vh; }

.landing { margin: -1.4rem -1.8rem 0; }
.l-nav { display: flex; align-items: center; gap: 1.1rem; padding: .8rem 2.4rem;
         background: var(--panel); border-bottom: 1px solid var(--line);
         position: sticky; top: 0; z-index: 40; }
/* Section anchors are the first thing to give when the labels are English or
   French rather than Japanese — the same links live in the footer. */
@media (max-width: 1240px) { .l-nav > a[href^="#"] { display: none; } }
@media (max-width: 1000px) { .l-nav .seg-label { display: none; } }
.l-nav a { font-weight: 600; font-size: .86rem; color: var(--sub); white-space: nowrap; }
.l-nav a:hover { color: var(--ink); }
.l-nav .btn { color: #fff; } .l-nav .btn-secondary { color: var(--ink); }
.l-spacer { flex: 1; }
.l-langs { font-size: .78rem; color: var(--faint); }
.l-langs a { color: var(--sub); font-weight: 600; }
.l-hero { text-align: center; padding: 4.5rem 1.5rem 3rem; background: var(--panel);
          border-bottom: 1px solid var(--line); }
.l-hero h1 { font-size: 2.5rem; font-weight: 800; letter-spacing: -.02em; max-width: 760px;
             margin: 0 auto; line-height: 1.15; }
.l-sub { color: var(--sub); font-size: 1.05rem; max-width: 640px; margin: 1rem auto 1.4rem; }

/* On the landing the kicker is not a caption — it is the line that says what
   this place is before the headline lands, and the one a visitor skimming on
   a phone reads first. Bigger than the .68rem eyebrow used inside the app,
   with the tracking eased off so it does not turn into a ransom note. */
.l-hero .kicker { font-size: .95rem; letter-spacing: .11em; margin-bottom: .7rem; }
body.jp .l-hero .kicker { font-size: 1rem; letter-spacing: .04em; }

/* Trade-only, said once, above the first button. A private collector who
   registers costs a manual review and gets a rejection either way; better to
   be turned away by a sentence than by an email three days later. */
.l-trade { display: inline-flex; align-items: center; gap: .5rem;
           margin: 0 auto 1.7rem; padding: .45rem 1rem; border-radius: 999px;
           border: 1px solid var(--red-line); background: var(--red-soft);
           color: var(--red-deep); font-size: .8rem; font-weight: 700; }
body.jp .l-trade { border-radius: 4px; }
.l-ctas .btn { margin: 0 .3rem; }
.l-stats { display: flex; justify-content: center; gap: 3.2rem; margin-top: 2.6rem; }
.l-stats b { display: block; font-size: 1.7rem; font-weight: 800; }
.l-stats span { font-size: .7rem; font-weight: 700; text-transform: uppercase;
                letter-spacing: .09em; color: var(--sub); }
.l-sec { max-width: 1080px; margin: 0 auto; padding: 3.4rem 1.8rem; }
.l-sec-alt { max-width: none; background: var(--panel); border-top: 1px solid var(--line);
             border-bottom: 1px solid var(--line); }
.l-sec-alt > * { max-width: 1080px; margin-left: auto; margin-right: auto; }
.l-sec-head { text-align: center; margin-bottom: 2.2rem; }
.l-sec-head h2 { font-size: 1.55rem; margin: .2rem 0; }
.l-sec-head p { color: var(--sub); max-width: 640px; margin: .5rem auto 0; }
.l-steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.2rem; }
@media (max-width: 900px) { .l-steps { grid-template-columns: repeat(2, 1fr); } }
.l-step { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
          padding: 1.3rem 1.4rem; }
.l-sec-alt .l-step { background: var(--bg); }
.l-num { width: 30px; height: 30px; border-radius: 50%; background: var(--red); color: #fff;
         font-weight: 800; display: flex; align-items: center; justify-content: center;
         margin-bottom: .8rem; }
.l-step b { font-size: .95rem; }
.l-step p, .l-col p, .l-trust-card p { color: var(--sub); font-size: .84rem; margin: .4rem 0 0; }
.l-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.2rem; }
@media (max-width: 900px) { .l-cols { grid-template-columns: 1fr; } }
.l-col { background: var(--bg); border: 1px solid var(--line); border-radius: var(--r);
         padding: 1.3rem 1.4rem; }
.l-trust { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.2rem; }
@media (max-width: 900px) { .l-trust { grid-template-columns: repeat(2, 1fr); } }
.l-trust-card { border-top: 3px solid var(--red); background: var(--panel);
                border-left: 1px solid var(--line); border-right: 1px solid var(--line);
                border-bottom: 1px solid var(--line); border-radius: 0 0 var(--r) var(--r);
                padding: 1.2rem 1.3rem; }
.l-faq { max-width: 720px; margin: 0 auto; }
.l-faq details { background: var(--bg); border: 1px solid var(--line); border-radius: 7px;
                 padding: .9rem 1.2rem; margin-bottom: .6rem; }
.l-faq summary { font-weight: 700; cursor: pointer; font-size: .9rem; }
.l-faq p { color: var(--sub); font-size: .85rem; margin: .6rem 0 0; }
.l-cta-band { background: var(--red); color: #fff; text-align: center; padding: 3.2rem 1.5rem; }
.l-cta-band h2 { color: #fff; font-size: 1.6rem; margin: 0 0 .4rem; }
.l-cta-band p { opacity: .9; margin: 0 0 1.4rem; }
.l-foot { display: flex; align-items: center; gap: 1.4rem; padding: 1.4rem 2.4rem;
          background: var(--panel); border-top: 1px solid var(--line); font-size: .82rem; }
.l-foot a { color: var(--sub); font-weight: 600; white-space: nowrap; }
.l-foot { flex-wrap: wrap; row-gap: .6rem; }
/* When a page brings its own auth-card (e.g. the wider register form), the
   layout's wrapper collapses to avoid a double frame. */
.auth-card:has(> .auth-card), .auth-card:has(> .auth-split) {
  background: transparent; border: none; box-shadow: none; padding: 0; width: auto; }

/* ── Registration: form beside the pitch ───────────────────────────────────
   The form alone was a 520px box in the middle of a 1440px screen, which
   reads as a page that failed to load rather than a company worth handing a
   VAT number to. The aside carries the same three claims the landing leads
   with, next to the form instead of behind it, and collapses under it on a
   narrow screen — never beside a form that would then be too cramped to
   fill in. */
.auth-split { display: grid; grid-template-columns: minmax(0, 580px) minmax(0, 310px);
              gap: 1.5rem; align-items: start; }
.auth-card-wide { width: min(580px, 100%); }

.auth-aside { display: flex; flex-direction: column; gap: 1rem; }
.auth-aside .l-trade { margin: 0; align-self: flex-start; font-size: .76rem; padding: .4rem .85rem; }
.auth-aside .how-it-works { background: var(--panel); }

.auth-facts { display: grid; grid-template-columns: repeat(3, 1fr); gap: .6rem;
              padding: .1rem .2rem; }
.auth-facts b { display: block; font-size: 1.05rem; font-weight: 800;
                background: var(--holo-ink); -webkit-background-clip: text;
                background-clip: text; color: transparent; }
.auth-facts span { font-size: .6rem; font-weight: 700; text-transform: uppercase;
                   letter-spacing: .07em; color: var(--sub); line-height: 1.3;
                   display: block; margin-top: .15rem; }
/* Flat surface: the foil is the one thing the JP layer removes everywhere. */
body.jp .auth-facts b { background: none; color: var(--red); }

@media (max-width: 980px) {
  .auth-split { grid-template-columns: minmax(0, 580px); }
  .auth-aside { order: 2; }
  .auth-facts { padding-bottom: .4rem; }
}

/* ── Legal pages ───────────────────────────────────────────────────────── */
.legal-page { margin: -1.4rem -1.8rem 0; display: flex; flex-direction: column;
              min-height: calc(100vh - 1.4rem); }
.legal-page > .l-foot { margin-top: auto; }
.legal-head { display: flex; align-items: center; gap: 1.2rem; padding: .8rem 2.4rem;
              background: var(--panel); border-bottom: 1px solid var(--line); }
/* Declared after the three rows so it overrides their padding shorthand: the
   band spans the viewport, its contents stay inside the 1240px column. */
.l-nav, .l-foot, .legal-head { padding-inline: max(2.4rem, calc((100% - 1240px) / 2)); }
/* .legal-page is a flex column, so an auto-margin child shrinks to its content
   instead of filling its max-width — width:100% is what makes the column real. */
.legal-body { width: 100%; max-width: 780px; margin: 0 auto; padding: 2.6rem 1.8rem 3rem; }
.public-body { width: 100%; max-width: 1080px; margin: 0 auto; padding: 2.5rem 1.4rem 4rem; }
.legal-body h1 { font-size: 1.8rem; margin: .2rem 0 .5rem; }
.legal-body h2 { font-size: 1rem; margin: 2rem 0 .5rem; }
.legal-body p, .legal-body li { color: var(--sub); font-size: .88rem; line-height: 1.7; }
.legal-body ul { padding-left: 1.1rem; }
.legal-body li { margin-bottom: .3rem; }
.legal-body b { color: var(--ink); }
.legal-body a { color: var(--red); font-weight: 600; }
.legal-meta { font-size: .78rem !important; color: var(--faint) !important; margin: 0 0 1.6rem; }
.legal-operator { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
                  padding: 1rem 1.2rem; font-size: .82rem; color: var(--sub); line-height: 1.7;
                  margin-bottom: 1.8rem; }
.legal-operator b { display: block; font-size: .66rem; text-transform: uppercase;
                    letter-spacing: .12em; color: var(--faint); margin-bottom: .3rem; }
.legal-note { background: var(--red-soft); border: 1px solid var(--red-line); border-radius: var(--r);
              padding: .9rem 1.1rem; font-size: .8rem; color: var(--red-deep); margin-bottom: 1.6rem; }
.legal-table { width: 100%; border-collapse: collapse; margin: .8rem 0 1rem; font-size: .82rem; }
.legal-table th { text-align: left; font-size: .64rem; text-transform: uppercase; letter-spacing: .09em;
                  color: var(--sub); padding: .45rem .8rem .45rem 0; border-bottom: 1px solid var(--line-2); }
.legal-table td { padding: .5rem .8rem .5rem 0; border-bottom: 1px solid #eef0f3; color: var(--sub); }

/* ── Claim conversation ────────────────────────────────────────────────── */
.claim-thread { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
                padding: 1.2rem 1.4rem; margin-bottom: 1.1rem; }
.claim-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; }
.claim-thread .msg { max-width: 82%; }
.claim-msg-buyer { align-self: flex-start; }
.claim-msg-seller { align-self: flex-end; background: var(--red-soft); border-color: var(--red-line); }
.claim-msg-platform { align-self: center; max-width: 92%; background: var(--info-soft);
                      border-color: var(--info-line); }
.claim-msg-internal { background: #fff8e5; border-color: #e8d9a8; }
.claim-thread .msg p { margin: .2rem 0 0; }

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE
   The shop floor is the primary context: a phone, one hand, standing up.
   Below 860px the dark sidebar is replaced by a top app bar and a fixed
   bottom tab bar, both rendered from the same nav_items list.
   ══════════════════════════════════════════════════════════════════════════ */

.appbar, .tabbar { display: none; }

@media (max-width: 860px) {
  .shell { grid-template-columns: 1fr; grid-template-rows: auto 1fr;
           align-content: start; background: none; }
  .sidebar { display: none; }

  .appbar {
    display: flex; align-items: center; gap: .6rem;
    position: sticky; top: 0; z-index: 40;
    padding: .55rem 1rem calc(.55rem);
    padding-top: calc(.55rem + env(safe-area-inset-top));
    background: var(--side); color: #fff;
  }
  .appbar .brandmark { color: #fff !important; font-size: .9rem; margin: 0; }

  /* Secondary destinations + language + logout, behind one tap. <details> so
     it works with Turbo without any JS to re-bind. */
  .appmenu { position: relative; }
  .appmenu > summary {
    list-style: none; cursor: pointer; font-size: 1.15rem; line-height: 1;
    padding: .45rem .6rem; border-radius: 8px; color: #fff;
    background: rgba(255, 255, 255, .1);
    min-width: 44px; min-height: 44px;
    display: flex; align-items: center; justify-content: center;
  }
  .appmenu > summary::-webkit-details-marker { display: none; }
  .appmenu[open] > summary { background: rgba(255, 255, 255, .2); }
  .appmenu-sheet {
    position: absolute; right: 0; top: calc(100% + .5rem); z-index: 50;
    min-width: 15rem; padding: .7rem; border-radius: 12px;
    background: var(--panel); border: 1px solid var(--line);
    box-shadow: 0 12px 32px rgba(16, 18, 22, .18); color: var(--ink);
  }
  .appmenu-who { font-size: .74rem; color: var(--faint); padding: .1rem .4rem .5rem;
                 border-bottom: 1px solid var(--line); margin-bottom: .4rem; }
  .appmenu-link { display: flex; align-items: center; gap: .6rem; min-height: 44px;
                  padding: .4rem; border-radius: 8px; color: var(--ink);
                  text-decoration: none; font-size: .88rem; font-weight: 600; }
  .appmenu-link:hover { background: var(--wash); }
  .appmenu-sheet .lang-switch { width: 100%; justify-content: center; margin-top: .5rem; }
  .appmenu-sheet form { margin: 0; }
  .appmenu-sheet .btn { width: 100%; }

  .tabbar {
    display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
    background: var(--panel); border-top: 1px solid var(--line);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .tab { display: flex; flex-direction: column; align-items: center; justify-content: center;
         gap: .15rem; min-height: 56px; padding: .4rem .2rem;
         color: var(--faint); text-decoration: none; }
  .tab-icon { position: relative; font-size: 1.15rem; line-height: 1; }
  .tab-label { font-size: .62rem; font-weight: 700; letter-spacing: .01em;
               max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .tab.on { color: var(--red); }
  .tab-dot { position: absolute; top: -2px; right: -6px; width: 7px; height: 7px;
             border-radius: 50%; background: var(--red); }

  /* Room for the fixed bar, plus a thumb's worth of slack. */
  main.container { padding: 1rem 1rem calc(5.5rem + env(safe-area-inset-bottom)); }

  /* Three KPI tiles should fit one row on a phone, not 2 + an orphan. */
  .stats-bar { grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: .55rem; }
  .stats-bar .stat { padding: .6rem .7rem; }
  .stats-bar .num { font-size: 1.15rem; }

  .page-head { flex-direction: column; align-items: flex-start; gap: .7rem; }
  .page-head h1 { font-size: 1.25rem; }
  .page-head .actions { width: 100%; display: flex; flex-wrap: wrap; gap: .5rem; }
  .page-head .actions form { margin: 0; }

  .grid-2, .form-layout, .rail-layout { grid-template-columns: 1fr; }
  .card { padding: 1rem; }
  .card-narrow, .col-narrow { max-width: none; }
  .deal-grid { grid-template-columns: repeat(2, 1fr); }
  .l-steps, .l-trust, .l-cols, .market-cards { grid-template-columns: 1fr; }
  .l-stats { display: grid; grid-template-columns: repeat(3, 1fr);
             gap: 1.2rem .6rem; text-align: center; }
  .l-stats b { font-size: 1.35rem; }
  .l-nav { flex-wrap: wrap; row-gap: .6rem; padding: .8rem 1rem; }
  .l-hero { padding: 3rem 1.1rem 2rem; }
  .display, .hero h1 { font-size: 1.7rem; }
  .legal-page { margin: 0; }
  .landing { margin: -1rem -1rem 0; }
  .legal-head { flex-wrap: wrap; row-gap: .6rem; padding: .8rem 1rem; }
  .legal-body { padding: 1.8rem 1.1rem 2.4rem; }
  .l-foot { padding: 1.2rem 1.1rem calc(1.2rem + env(safe-area-inset-bottom)); }

  /* Tables become cards: a 6-column table on a 390px screen is unreadable
     however you scroll it. Each cell carries its header via data-label. */
  table.list, table.list tbody, table.list tr, table.list td { display: block; width: 100%; }
  table.list thead, table.list tr:first-child th { display: none; }
  table.list tr {
    background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
    margin-bottom: .7rem; padding: .3rem .2rem; }
  table.list td {
    display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
    border: none; border-bottom: 1px solid #f1f2f4; padding: .5rem .8rem;
    text-align: right; }
  table.list td:last-child { border-bottom: none; }

  /* The first cell is the card's subject — give it the weight of a heading
     instead of squeezing it into a right-aligned label/value row. */
  table.list td:first-child {
    display: block; text-align: left; font-size: .95rem; font-weight: 700;
    padding: .7rem .8rem .55rem; }
  table.list td:first-child::before { display: none; }
  table.list td:first-child a { color: inherit; text-decoration: none; }

  /* Zebra striping belongs to a table, not to a list of cards. */
  table.list tr:nth-child(even), table.list tr:nth-child(odd) { background: var(--panel); }

  /* Action cells have no header, and render nothing when the action does not
     apply — an empty row with a divider. */
  table.list td:not([data-label]):not(:has(*)) { display: none; }
  table.list td::before {
    content: attr(data-label); flex: 0 0 auto; text-align: left;
    font-size: .62rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: .08em; color: var(--sub); }
  table.list td:empty { display: none; }
  table.list td.num { text-align: right; }

  /* iOS zooms the whole page when a focused input is under 16px, and does not
     zoom back when you leave the field — you finish the form at 130%, panning.
     This is one of the two things that made every form here feel broken on a
     phone, and the rule meant to prevent it never applied: it was written as
     `form.stacked input`, while the base size is set per input[type=…], which
     outranks it. Hence !important — the guard has to beat a typed selector it
     cannot out-specify without listing every type twice. */
  input:not([type=hidden]), select, textarea { font-size: 16px !important; }

  .btn { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
  .btn-sm { min-height: 38px; }

  /* Thumb-sized: the language segments were 24px tall and the landing's own
     links 21px, well under the 44px a fingertip actually covers. The segment
     wrapper has to become a flex item along with them, or the pill keeps its
     old height and the two segments overlap inside it. */
  .lang-switch { align-items: stretch; }
  .lang-switch .lang-switch-form { display: inline-flex; }
  .lang-switch a, .lang-switch button, .l-nav > a, .l-foot > a, .auth-card .brandmark {
    min-height: 40px; display: inline-flex; align-items: center; justify-content: center; }
  .lang-switch a, .lang-switch button { padding-inline: 1.1rem; font-size: .78rem; }
  .thread li { max-width: 100%; }
}

@media (max-width: 420px) {
  .deal-grid { grid-template-columns: 1fr; }
  .l-stats { grid-template-columns: 1fr; }
  .tab-label { font-size: .58rem; }
}

/* Installed as a home-screen app: no browser chrome, so pull the app bar down
   past the status bar and keep the tab bar clear of the home indicator. */
@media (display-mode: standalone) {
  .appbar { padding-top: calc(.55rem + env(safe-area-inset-top)); }
  body { overscroll-behavior-y: none; }
}

/* Respect the OS setting rather than animating regardless. */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ── Mobile refinements ─────────────────────────────────────────────────── */
@media (max-width: 860px) {
  /* The header row of a stacked table would otherwise render as an empty card. */
  table.list tr:has(> th) { display: none; }

  /* Secondary content belongs after the work on a phone. */
  .rail-layout > div { display: flex; flex-direction: column; }
  .order-last-on-mobile { order: 99; margin-top: 1.4rem; }

  /* A dl with a long value reads better stacked than squeezed into 2 columns. */
  dl.kv { grid-template-columns: 1fr; }
  dl.kv dt { padding: .5rem 0 .1rem; border-bottom: none; font-size: .72rem;
             text-transform: uppercase; letter-spacing: .06em; }
  dl.kv dd { padding: 0 0 .55rem; }
  dl.kv dd.num { text-align: left; }
  dl.kv dt:last-of-type { border-bottom: none; }

  /* There is no hover on a phone, and no room for a floating panel either. */
  .card-zoom { display: none !important; }

  /* Tap targets in the negotiation thread and pill rows. */
  .pill-row { row-gap: .4rem; }
  .filter-row a { min-height: 38px; display: inline-flex; align-items: center; }
}

@media (max-width: 860px) {
  .appback { display: flex; align-items: center; justify-content: center;
             min-width: 44px; min-height: 44px; margin-left: -.4rem;
             font-size: 1.6rem; line-height: 1; color: #fff; text-decoration: none; }
  .apptitle { font-size: .92rem; font-weight: 700; color: #fff;
              overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* Native <details> markers look like a debug view next to a styled FAQ.
     Laid out as a row rather than a floated marker so the whole question is
     one 44px target — at 22px tall these were the smallest thing on the page
     a visitor is actually meant to tap. */
  .l-faq summary { list-style: none; display: flex; align-items: center;
                   justify-content: space-between; gap: 1rem; min-height: 44px; }
  .l-faq summary::-webkit-details-marker { display: none; }
  .l-faq summary::after { content: "+"; font-weight: 700; color: var(--red); }
  .l-faq details[open] summary::after { content: "–"; }
}

/* ─────────────────────────────────────────────────────────────────────────────
   Collector layer — public pages only.

   The buyers are card and hobby shops; the goods are collectibles. The
   cockpit stays a cockpit once you are signed in — this layer only touches
   the pages a stranger sees, and borrows the one visual cue everyone in this
   trade reads instantly: the holo foil of a rare card.

   Deliberately generic foil, not any publisher's palette or wordmark — the
   platform sells to shops that trade Pokémon, it is not licensed by them.
   ───────────────────────────────────────────────────────────────────────── */
:root {
  --holo: linear-gradient(115deg, #ffcf5c 0%, #ff6f9c 22%, #a06bff 45%,
                                  #3fc9ff 66%, #48e39b 84%, #ffcf5c 100%);
  --holo-soft: linear-gradient(115deg, rgba(255,207,92,.16), rgba(255,111,156,.16),
                               rgba(160,107,255,.16), rgba(63,201,255,.16), rgba(72,227,155,.16));
  /* Foil for text. Starts on the brand vermillion so a headline number still
     reads as ours rather than as a generic rainbow. */
  --holo-ink: linear-gradient(100deg, #c0351f 0%, #e0642c 30%, #b0489a 62%, #3f7fd8 100%);
}

/* ── Hero: an aurora behind the type, a foil edge under it ─────────────── */
.l-hero { position: relative; overflow: hidden; border-bottom: none; }
.l-hero::before {
  content: ""; position: absolute; inset: -40% -10% auto -10%; height: 150%;
  pointer-events: none; z-index: 0;
  background:
    radial-gradient(42% 55% at 18% 30%, rgba(216, 68, 46, .13), transparent 70%),
    radial-gradient(38% 50% at 82% 22%, rgba(160, 107, 255, .13), transparent 70%),
    radial-gradient(46% 60% at 55% 88%, rgba(63, 201, 255, .11), transparent 72%);
}
.l-hero > * { position: relative; z-index: 1; }
/* The foil strip reads as the edge of a card, and separates hero from body. */
.l-hero::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0;
                 height: 3px; background: var(--holo); z-index: 2; }

/* Big numbers pick up the foil instead of sitting flat black. */
.landing .l-stats b { background: var(--holo-ink); -webkit-background-clip: text;
                      background-clip: text; color: transparent; }

/* ── Cards that behave like cards ──────────────────────────────────────── */
.l-step, .l-trust-card, .market-card, .l-col {
  position: relative; overflow: hidden; border-radius: 12px;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
/* Foil cap along the top edge — the trust cards already had a red one. */
.l-step::before, .market-card::before, .l-col::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: var(--holo); opacity: .85;
}
.l-trust-card { border-top-width: 3px; border-top-style: solid; border-image: var(--holo) 1; }

/* The shine sweep: a diagonal highlight that crosses the card once on hover,
   the way a foil catches the light when you tilt it. It is an animation, not
   a transition, so it passes and clears instead of parking a tinted half-card
   under the cursor for as long as the pointer rests there. */
@keyframes foil-sweep {
  0%   { opacity: 0;   transform: translateX(-75%); }
  22%  { opacity: .95; }
  100% { opacity: 0;   transform: translateX(75%); }
}
.l-step::after, .l-trust-card::after, .market-card::after, .l-col::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0;
  background: linear-gradient(115deg, transparent 38%, rgba(255,255,255,.9) 50%,
                              transparent 62%), var(--holo-soft);
}
.l-step:hover, .l-trust-card:hover, .market-card:hover, .l-col:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 26px -12px rgba(26, 29, 33, .28);
}
.l-step:hover::after, .l-trust-card:hover::after,
.market-card:hover::after, .l-col:hover::after { animation: foil-sweep .8s ease-out; }
.market-card:hover { border-color: var(--line-2); }
.market-card > * { position: relative; z-index: 1; }

/* Step numbers read as energy pips rather than plain bullets. */
.l-num { box-shadow: 0 0 0 4px rgba(216, 68, 46, .12), 0 3px 8px -2px rgba(216, 68, 46, .5); }

/* ── Closing band: deeper, with a foil hairline ────────────────────────── */
.l-cta-band { position: relative;
              background: linear-gradient(118deg, var(--red-deep) 0%, var(--red) 48%, #a0364f 100%); }
.l-cta-band::before { content: ""; position: absolute; top: 0; left: 0; right: 0;
                      height: 3px; background: var(--holo); }

/* The market price hero is the page a collector lands on from search. */
.market-hero { position: relative; overflow: hidden; border-radius: 12px; }
.market-hero::before { content: ""; position: absolute; top: 0; left: 0; right: 0;
                       height: 3px; background: var(--holo); opacity: .85; }
.market-hero .big-price { background: var(--holo-ink); -webkit-background-clip: text;
                          background-clip: text; color: transparent; }

/* Reduced motion: keep the foil, drop the movement. */
@media (prefers-reduced-motion: reduce) {
  .l-step, .l-trust-card, .market-card, .l-col { transition: none; }
  .l-step:hover, .l-trust-card:hover, .market-card:hover, .l-col:hover { transform: none; }
  .l-step::after, .l-trust-card::after, .market-card::after, .l-col::after { display: none; }
}

/* ─────────────────────────────────────────────────────────────────────────────
   JP surface — the seller side (body.jp, set by the public layout).

   A Japanese shop's reference for "an online marketplace that is safe to sign
   up to" is Mercari, and Mercari is the opposite of the collector layer above:
   flat white, 4px corners, red reserved strictly for actions, Hiragino, no
   ornament at all. Foil on that page would read as a consumer-grade gimmick to
   exactly the audience we most need to look boring and trustworthy to.

   Borrowed from Mercari: white page, ink #333 / sub #666, 4px radius, 15px
   body, Hiragino. NOT borrowed: their red. The vermillion is the one thing
   that has to be identical on both surfaces — it is in the logo mark, the
   favicon, the invoice PDFs and every transactional email, and a seller who
   sees one red on the landing and another on an invoice sees two companies.
   ───────────────────────────────────────────────────────────────────────── */
body.jp {
  --bg:      #ffffff;
  --panel:   #ffffff;
  --wash:    #fafafa;
  --line:    #eeeeee;
  --line-2:  #dddddd;

  --ink:     #333333;
  --sub:     #666666;
  --faint:   #888888;

  --r: 4px;
  --font: "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Noto Sans JP", Meiryo,
          "Helvetica Neue", Arial, sans-serif;

  font-size: 15px;
}

/* No foil, no aurora, no lift. The JP page earns trust by being plain. */
body.jp .l-hero::before,
body.jp .l-hero::after,
body.jp .l-step::before, body.jp .l-col::before, body.jp .market-card::before,
body.jp .market-hero::before,
body.jp .l-cta-band::before,
body.jp .l-step::after, body.jp .l-trust-card::after,
body.jp .market-card::after, body.jp .l-col::after { display: none; }
body.jp .l-step:hover, body.jp .l-trust-card:hover,
body.jp .market-card:hover, body.jp .l-col:hover { transform: none; box-shadow: none; }
body.jp .l-step, body.jp .l-trust-card, body.jp .l-col,
body.jp .market-card, body.jp .market-hero { border-radius: 4px; }
body.jp .l-trust-card { border: 1px solid var(--line-2); border-top: 2px solid var(--red);
                        border-image: none; }
body.jp .l-num { box-shadow: none; }

/* Solid brand red, not a gradient — Mercari never tints a numeral. */
body.jp .l-stats b, body.jp .market-hero .big-price {
  background: none; -webkit-text-fill-color: currentColor; color: var(--red); }
body.jp .l-cta-band { background: var(--red); }

/* Swiss-plain type: smaller headings, normal tracking, no display weight. */
body.jp .l-hero { padding: 3.4rem 1.5rem 2.6rem; border-bottom: 1px solid var(--line); }
body.jp .display { font-size: 2rem; font-weight: 700; letter-spacing: normal; }
body.jp .l-sec-head h2 { font-size: 1.35rem; font-weight: 700; letter-spacing: normal; }
body.jp .kicker { letter-spacing: .08em; }
/* The JP surface exists to remove ornament, and the progress bar is ornament:
   a drifting rainbow across the top of every Mercari-flat page. Same red, no
   foil. The switcher shell was still a 999px capsule around 4px chips. */
body.jp .turbo-progress-bar { background: var(--red); animation: none; box-shadow: none; }
body.jp .lang-switch { border-radius: 4px; }
body.jp .l-faq details { border-radius: 4px; }
body.jp .l-sub { font-size: 1rem; }

/* Sections separate with a hairline instead of a grey block. */
body.jp .l-sec-alt { background: var(--panel); }
body.jp .l-sec + .l-sec, body.jp .l-sec-alt { border-top: 1px solid var(--line); }
body.jp .l-step, body.jp .l-sec-alt .l-step, body.jp .l-col,
body.jp .l-faq details { background: var(--wash); border-color: var(--line-2); }

/* Buttons: 4px, bold, red for the action and outlined for everything else. */
body.jp .btn { border-radius: 4px; font-weight: 700; }
body.jp .btn-secondary { border-color: var(--line-2); }
body.jp .lang-switch button { border-radius: 4px; }

/* The signup form is where the seller commits — it must not look like a
   different company from the page that sent them there. Mercari's own forms
   are a plain card on a faint grey field, square-ish corners, no shadow. */
body.auth.jp { background: #f7f7f7; }
body.auth.jp .auth-card { border-radius: 4px; box-shadow: none; border-color: var(--line-2); }

/* A submit button held disabled until the form is complete has to look
   unavailable, or it reads as a broken button rather than a pending one.
   Neutral rather than a faded red: a washed-out brand colour reads as a
   rendering fault on the one screen where a stranger is judging whether this
   platform is a real company. */
.btn[disabled], .btn[disabled]:hover { opacity: 1; cursor: not-allowed; box-shadow: none;
                                       background: var(--wash); color: var(--faint);
                                       border: 1px solid var(--line); }
.btn-secondary[disabled], .btn-secondary[disabled]:hover { background: var(--wash); color: var(--faint); }

/* A long address — "prenom.nom@boutique-de-cartes-dijon.example" — is wider
   than a 216px sidebar or a 15rem menu sheet, and was pushing the panel out
   of shape rather than wrapping. Truncate it and keep the full value in the
   title attribute, so hovering (or a screen reader) still gets all of it. */
.sidebar .foot b, .sidebar .foot .who, .appmenu-who {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 100%; min-width: 0;
}
/* The avatar must not shrink to make room for a long name — the name gives. */
.sidebar .foot .rowflex { min-width: 0; }
.sidebar .foot .rowflex > b { min-width: 0; }

/* ── Modal prompt ──────────────────────────────────────────────────────── */
/* Used for data the account cannot operate without — today only the buyer's
   delivery address. Deliberately not a dialog element: this must render
   identically with JavaScript off, where "later" is simply unavailable. */
.modal-scrim { position: fixed; inset: 0; z-index: 90; display: flex;
               align-items: center; justify-content: center; padding: 1.2rem;
               background: rgba(16, 18, 22, .55); }
.modal-card { background: var(--panel); border-radius: 12px; width: 100%; max-width: 440px;
              padding: 1.6rem 1.7rem; box-shadow: 0 18px 48px rgba(16, 18, 22, .3);
              max-height: 92vh; overflow-y: auto; }
.modal-actions { display: flex; gap: .6rem; justify-content: flex-end; margin-top: 1.3rem; }
.modal-actions .btn { width: auto; margin: 0; }
@media (max-width: 560px) { .modal-card { padding: 1.2rem 1.1rem; } }

/* Phone: a narrow country-code select welded to the number input, so the two
   read as one field rather than two unrelated controls. */
.phone-field { display: flex; gap: 0; }
/* Just wide enough for a flag and the longest code (+81) plus the native
   select arrow — it is a prefix, not a field in its own right. */
.phone-field select { flex: 0 0 6.3rem; padding-left: .55rem; padding-right: .2rem;
                      border-radius: 7px 0 0 7px; border-right: none; }
.phone-field input { flex: 1 1 auto; min-width: 0; border-radius: 0 7px 7px 0; }

/* The 1240px cap is right for a page that owns the whole viewport, but inside
   the shell the sidebar has already taken 216px, so the column ends up
   centred in what is left with a wide dead gutter on either side — on a
   2200px screen, ~370px of empty canvas each side of a dense table. Give the
   app column a cap of its own: wide enough to use a large monitor, bounded so
   a table row does not become a 3000px line nobody can scan. */
.shell main.container { max-width: 1680px; padding-left: 2rem; padding-right: 2rem; }
@media (min-width: 1900px) {
  /* Past this width the two-column dashboards have room for a real split
     rather than a narrow rail squeezed against the edge. */
  .shell main.container { padding-left: 2.6rem; padding-right: 2.6rem; }
}

/* The prompt has no "later", so it must never be a dead end: signing out is
   always one click away — on the same row as the action, pushed to the far
   side, so the eye reads "leave … or finish" rather than finding the escape
   stranded below the button it is an alternative to. */
.modal-actions { align-items: center; }
.modal-escape { margin: 0; margin-right: auto; }
.linklike { background: none; border: none; padding: 0; font: inherit;
            font-size: .78rem; color: var(--faint); cursor: pointer;
            text-decoration: underline; }
.linklike:hover { color: var(--sub); }

/* TOTP enrolment: the QR is the primary path, the typed secret the fallback. */
.totp-enrol { display: flex; gap: 1.4rem; align-items: flex-start; margin: 1.2rem 0 1.6rem; }
.totp-qr { flex: 0 0 auto; background: #fff; padding: .6rem; border: 1px solid var(--line);
           border-radius: 8px; line-height: 0; }
.totp-qr svg { width: 100%; height: auto; display: block; }
@media (max-width: 560px) { .totp-enrol { flex-direction: column; } }

/* ── Navigation progress ───────────────────────────────────────────────── */
/* Turbo's own bar is a flat blue that belongs to no design system in this
   app. Since it is the one piece of chrome a member sees on every single
   navigation, it may as well be the foil — the same cue the public pages use,
   here reduced to a 3px line. Turbo only inserts the element after 500ms, so
   this is never seen on a fast page. */
.turbo-progress-bar {
  height: 3px;
  background: var(--holo);
  background-size: 200% 100%;
  animation: holo-drift 1.6s linear infinite;
  box-shadow: 0 0 8px -1px rgba(216, 68, 46, .55);
}

@keyframes holo-drift {
  from { background-position:   0% 0; }
  to   { background-position: 200% 0; }
}

/* A bar that hurries is worse than no bar for anyone who finds motion
   uncomfortable; the colour still says "working". */
@media (prefers-reduced-motion: reduce) {
  .turbo-progress-bar { animation: none; }
}
