/* =====================================================================
   payment.css — お支払いについて page (/payment/)
   ---------------------------------------------------------------------
   This page is a sibling of /app/ and deliberately loads css/app.css
   before this file: the hero, the four-fact strip, the ruled step
   columns, the two-column shot-beside-copy block, the feature table and
   the FAQ recipe are all already designed there, and re-cutting them
   here would be a second dialect of the same page family. The body
   carries BOTH `page-app` and `page-payment` so app.css's ink tokens
   (--app-ink-sky / --app-ink-amber / --app-ink-quiet), its type scale
   and its reduced-motion block apply unchanged.

   Only what /app/ has no component for lives here, in source order:
     1. .pay-price     — 入会金 + the four monthly fees, as one panel
     2. .pay-brands    — the accepted card brands, as chips
     3. .pay-safe      — the four reassurance cards
     5. .pay-callout   — a single emphasised note inside a section
     6. .pay-rules     — 振替・キャンセル・退会 as a definition table
     7. narrow phones

   Responsive contract: fluid from 320px up. The ramp this file actually
   ships, and why each step exists:
     1023  the two card grids go 2-up and share a 20px gutter
      767  .pay-safe goes 1-up
      600  .pay-price-table and .pay-rules-table restack into blocks
      389  the hero frame drops its gutters so the mock keeps its 302px
      360  the price panel tightens its side padding
      349  both mocks are scaled a second step to fit a 272px column
   (It previously claimed 520/767/1023. 520 is never used, and the --sp-7
   bug shipped through 767 — a width the contract named but nothing checked.
   Keep this list honest: it is the checklist a reviewer works from.)
   ===================================================================== */


/* ---------------------------------------------------------------------
   0. HERO — /app/ hangs its phone off the corner of a desktop window
   shot, so .app-hero-phone is absolutely positioned and .app-hero-visual
   is only tall enough to clear the overhang. This page has no window
   mock, so that phone rides straight up over the headline. Here it is
   set STATIC and centred instead, inside a fixed-height frame that crops
   it to the top of the お支払い情報 screen — the registered cards, which
   is exactly what the headline promises — and fades the cut into the
   cream. The whole screen is shown further down, beside its own copy.
--------------------------------------------------------------------- */
.page-payment .app-hero-visual {
  width: 100%;
  max-width: 330px;
  /* Fixed, not clamped, and the fade is set in pixels rather than percent.
     Both follow from the same thing: the cut has to land BETWEEN two rows of
     the card list, and a percentage stop moves with the frame height while
     the rows do not. On a clamp(290,32vw,400) frame with the stop at 74% the
     fade began inside the VISA row at every width from 320 to 1132 — the
     first row of the list the headline is pointing at was the one row served
     half-ghosted. The list sits at 206-271 (VISA), 271-337 (Apple Pay) and
     337-403 (Link) inside this mock, so opaque to 271 gives a solid first
     row, a second row that fades, and a third that suggests more below. */
  height: 366px;
  margin: var(--sp-12) auto 0;
  /* Side gutters so the phone's drop shadow has somewhere to land: with the
     frame clipping flush to the bezel, the shadow was declared and then cut
     off on both edges, and the mock read as a panel rather than an object. */
  padding: 0 14px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, #000 0, #000 271px, transparent 366px);
          mask-image: linear-gradient(180deg, #000 0, #000 271px, transparent 366px);
}
/* display:block re-asserted — app.css hides the phone below 900px, where
   it would collide with the window mock this page does not have. */
.page-payment .app-hero-phone {
  display: block;
  position: static;
  width: 100%;
  filter: none;
}
/* zoom:1 deliberately cancels app-mock.css's site-wide narrow-phone net
   (0.9 below 420px, 0.8 below 360px): this frame does its own scaling at
   349px so the shot stays as large as the column allows. That leaves four
   separately-owned numbers holding the mock's fit — --content-pad-x
   (base.css), the 330px frame and 14px gutters here, and the 389/349
   breakpoints. Change any one and re-measure the 今後のお支払い予定 tiles,
   which need 302px of phone to lay out. */
.page-payment .app-hero-phone .app-phone {
  zoom: 1;
  box-shadow: 0 30px 60px -24px rgba(31, 26, 20, 0.28);
}
/* Out of the absolute corner and back into the hero's flex column, so it
   sits under the cropped shot rather than over the section below it. */
.page-payment .app-hero-caption {
  position: static;
  justify-content: center;
  margin-top: var(--sp-4);
  padding-bottom: var(--sp-12);
}
.page-payment .app-hero-caption::before { display: none; }

/* The 「アプリの中に」 block reuses /app/'s .app-platform. That section is
   tuned for platform-devices — a wide, short composition it can afford to
   scale up by 1.3 (app.css:978). The お支払い情報 phone is a tall single
   column, so it is scaled DOWN instead. 0.85 is a balance number, not a
   fitting one: at native size the pinned frame stands 735px against a text
   column of 548px, and the grid centres them, so 219px of the band was void
   beside the copy. 0.85 takes the frame to 625px and the overhang to 109px,
   which reads as a tall object beside a shorter one rather than a slab with
   text floating next to it. In-phone base type lands at 11.5px, still above
   the 0.76 the feature cards on this same page already ship (app.css:732).
   (735px is not itself out of range — /app/ carries a 786px phone — so this
   is not a correction, it is composition.) */
.page-payment .app-platform-visual .jse-mock { zoom: 0.85; }

/* Hold the screen at a real handset's proportions. Nothing else on the site
   pins a phone's height — every .app-phone is as tall as whatever fragment
   is poured into it — and that is exactly how this one reached 330 x 1010
   (ratio 3.06) while /app/'s own shots sit between 1.9 and 2.2. An iPhone's
   display is 19.5:9 = 2.167, so at the 330px screen width this frame gives
   (350 less the 10px bezel on each side) the screen is 715px and the outer
   frame 735px — ratio 2.10, which is the body ratio of the handset itself.
   partials/app/payment-schedule.php is written to come in just under that,
   so the spare pixels read as empty canvas below the last row, the way a
   real screen does. overflow:hidden is the guarantee, not the mechanism: if
   a future edit overruns, the shot stays phone-shaped and the surplus is
   clipped rather than stretching the frame back out. */
.page-payment .app-platform-visual .app-phone-screen {
  aspect-ratio: 9 / 19.5;
  overflow: hidden;
}
/* The pin alone is not a clip contract. .app-phone-screen is a flex column of
   status bar / body / home indicator (app-mock.css:473), and .app-phone-body
   is flex:1 with no min-height:0, so a body that overruns refuses to shrink
   and the overflow is taken off the BOTTOM of the screen — the home indicator
   goes first, then the last row is cut with a hard edge. Let the body shrink,
   and fade the cut the way every other clipped shot on this site does
   (app.css:941, app-mock.css:639 — the 40px band is the site constant). */
.page-payment .app-platform-visual .app-phone-body {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 40px), transparent 100%);
          mask-image: linear-gradient(180deg, #000 calc(100% - 40px), transparent 100%);
}
/* Scale the shot instead of reflowing it, so the fragment's height and the
   pinned frame shrink together and the fade never has anything to hide.
   Left to reflow, the frame narrows (width:100%) while the content does not,
   and the content overran the pin by 65px at 400px and 131px at 360px — the
   whole お支払い履歴 block, which is a third of what the heading promises.
   The frame is 350px wide and the column is the viewport less 48px of gutter,
   so 350 stops fitting at 398px; each step is the largest zoom that still
   fits at the narrowest viewport in its range (350 x 0.86 = 301 <= 302 at
   350px; 350 x 0.77 = 270 <= 272 at 320px). The hero's own ramp steps at
   389/349 rather than 399/349 because its frame is 330px, not 350px. */
.page-payment .app-platform-visual .app-phone {
  zoom: 1;                 /* cancel app-mock.css:616-621's narrow-phone net */
  width: 350px;
  max-width: none;
}
/* One step, not two: at 0.85 the frame is 297px and the column is the
   viewport less 48px of gutter, so it already fits every viewport down to
   346px and the old 399px step would now make the shot GROW on small
   phones. Below that, 0.76 gives 266px inside the 272px a 320px viewport
   leaves — and 0.76 is the site's own number at app.css:732. */
@media (max-width: 349px) {
  .page-payment .app-platform-visual .jse-mock { zoom: 0.76; }
}

/* Below ~350px the hero frame is narrower than the お支払い情報 mock's own
   350px design width, and the two 今後のお支払い予定 tiles squeeze until
   「¥16,500」 no longer fits its cell (13px short at 320px, 3px at 340px).
   Hold the frame at a fixed width and scale it instead of letting the mock
   reflow — the same lever /app/ pulls with zoom on .jse-mock. 310 x 0.86 =
   267px, inside the 272px the narrowest supported viewport leaves. */
/* Two steps down, both set by where the mock physically stops fitting.
   The shot needs 302px to lay out the 今後のお支払い予定 tiles, so below
   390px the gutters go first — at that width the shot needs the pixels more
   than it needs its shadow — and below 350px even the full frame is too
   narrow, so the mock is pinned to a fixed width and scaled to fit the
   272px the narrowest supported viewport leaves (310 x 0.86 = 267px). */
@media (max-width: 389px) {
  .page-payment .app-hero-visual { padding-inline: 0; }
}
@media (max-width: 349px) {
  .page-payment .app-hero-visual .app-phone { width: 310px; max-width: none; }
  .page-payment .app-hero-visual .jse-mock { zoom: 0.86; }
  /* zoom moves the rows with it: 271 x 0.86 = 233, 366 x 0.86 = 315. */
  .page-payment .app-hero-visual {
    height: 315px;
    -webkit-mask-image: linear-gradient(180deg, #000 0, #000 233px, transparent 315px);
            mask-image: linear-gradient(180deg, #000 0, #000 233px, transparent 315px);
  }
}


/* ---------------------------------------------------------------------
   0b. BAND RHYTHM
   Every other page on the site alternates white / cream strictly, with no
   two adjacent bands sharing a ground: /, /about/ and /app/ all do. That
   works there because each has an ODD number of content bands between the
   cream hero block and the cream CTA, so the run starts and ends white.
   This page has eight, so one pair has to share a ground. It is placed on
   安心のしくみ + 振替・退会 — the two "before you commit" sections, which
   read as one block — rather than anywhere the reader is still scanning.

   The two app.css sections below carry their own background and ignore
   .section-alt, so the ground they take is set here, not in the markup:
   .section-app-platform is pulled to cream to keep the run alternating,
   and .section-app-faq keeps app.css's white so the FAQ meets the cream
   CTA exactly as it does on /app/ and on the home page.
--------------------------------------------------------------------- */
.page-payment .section-app-platform { background: var(--bg-cream); }


/* ---------------------------------------------------------------------
   0c. PROSE MEASURE
   layout.css caps .section-desc at 42em with the note that "a JP measure
   past ~45 characters stops scanning", and legal.css caps its own long-form
   column at 40rem. .pay-callout was set to 720px to match app.css's centred
   .app-flow-note — but that note is centred text, where a short last line
   reads as deliberate, while these callouts are left-aligned prose in a box,
   where 48em left three of them stranding a three-to-five character last
   line at every width from 768px up. 42em is the site's own figure.

   Measured over 390 / 768 / 1024 / 1280px, short last lines drop from 20 to
   11 (10.3% of blocks to 5.6%, against /app/'s own 4.0%) with average line
   fill unchanged at 94.3%. `word-break: auto-phrase` would take it to 1.0%,
   but costs 8 points of line fill (86.1%): it can only break between
   phrases, so every line stops early and the rag opens up. That is why
   layout.css scopes auto-phrase to the display primitives and leaves
   running copy alone — and why this page does too.
--------------------------------------------------------------------- */


/* ---------------------------------------------------------------------
   1. PRICE PANEL — 入会金 once, then a row per course.
   A real <table>, because it IS one: four courses against three facts.
   Below 600px the <thead> is hidden and each row restacks into a block, so
   the numbers never squeeze into 40px. The column headers are dropped
   rather than reproduced per cell: every value is self-describing
   (「週1回 / 45分」, 「17,600円/月」). A value that is NOT self-describing
   needs data-label + content: attr(data-label) adding here first.
--------------------------------------------------------------------- */
.pay-price {
  max-width: 800px;
  margin: 0 auto;
  background: var(--bg-white);
  border: 1px solid var(--border-warm);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

/* 入会金 — the one-off, held apart from the recurring table above it.

   This is the page's one display figure. Everything else on /payment/ tops
   out at --fs-h2 (26px), which is why the whole page weighed the same from
   top to bottom: index.php changes scale twice a screen (the 98% / 84% discs
   at home.css:256, the 合格までの軌跡 banner at home.css:1885) and this page
   never did. The number a parent actually carries away from here is 22,000,
   so it gets the .hero-stat-num treatment verbatim — Montserrat 800 in brand
   blue over the 40 x 3px amber rule — and nothing else on the page competes. */
.pay-price-once {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-3) var(--sp-6);
  padding: var(--sp-6) var(--sp-8);
  background: var(--bg-warm);
  border-bottom: 1px solid var(--border-warm);
}
.pay-price-once-head {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  min-width: 0;
}
.pay-price-once-label {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: var(--fw-bold);
  color: var(--text-main);
}
.pay-price-once-note {
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  color: var(--app-ink-quiet);
}
.pay-price-once-figure {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--sp-2);
  margin: 0;
}
.pay-price-once-value {
  font-family: var(--font-en);
  font-size: clamp(2.4rem, 4.4vw, 3.2rem);
  line-height: var(--lh-num);
  font-weight: var(--fw-head);
  letter-spacing: -0.02em;
  color: var(--primary);
  font-variant-numeric: tabular-nums;
}
.pay-price-once-unit {
  font-family: var(--font-ja);
  font-size: 0.34em;
  font-weight: var(--fw-bold);
  color: var(--text-main);
  margin-left: 0.18em;
}
/* The gold rule under the figure — home.css:1908 .success-stat-rule. */
.pay-price-once-rule {
  width: 40px;
  height: 3px;
  border-radius: 2px;
  background: var(--accent);
  opacity: 0.9;
}

.pay-price-table {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
}
.pay-price-table caption {
  padding: var(--sp-5) var(--sp-8) 0;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-bold);
  color: var(--text-main);
  text-align: left;
}
.pay-price-table th,
.pay-price-table td {
  padding: var(--sp-4) var(--sp-8);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  border-bottom: 1px solid var(--border-warm);
  vertical-align: middle;
}
.pay-price-table thead th {
  padding-top: var(--sp-4);
  padding-bottom: var(--sp-3);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-med);
  letter-spacing: 0.04em;
  color: var(--app-ink-quiet);
  white-space: nowrap;
}
.pay-price-table tbody tr:last-child th,
.pay-price-table tbody tr:last-child td { border-bottom: 0; }
.pay-price-table tbody th {
  font-weight: var(--fw-bold);
  color: var(--text-main);
  white-space: nowrap;
}
.pay-price-lesson { color: var(--text-light); white-space: nowrap; }
.pay-price-fee { text-align: right; white-space: nowrap; }
.pay-price-num {
  font-family: var(--font-en);
  /* A fixed 20px rather than a step from app.css's scale: every step at
     this size is fluid, and a fluid figure breaks the tabular alignment
     the fee column depends on. */
  font-size: 1.25rem;
  font-weight: var(--fw-head);
  letter-spacing: var(--ls-num);
  font-variant-numeric: tabular-nums;
  /* Brand blue, not ink: the site prints every fee figure in --primary and
     leaves its unit and cycle in ink (home.css:3016 .course-card-price-num).
     The fee is the one thing a reader came to this table for, and it was the
     only number on the page with no visual priority over the row label. */
  color: var(--primary);
}
.pay-price-unit { font-size: var(--fs-body-sm); font-weight: var(--fw-bold); margin-left: 0.15em; }
.pay-price-cycle { font-size: var(--fs-body-sm); color: var(--text-light); margin-left: 0.1em; }

/* 月4回 = 月謝. Set as an equation rather than a sentence: it is the one
   arithmetic step between the table above and the per-lesson billing the
   next section describes, and a reader who is unsure about it will not find
   the answer in a paragraph of body text. The 4 borrows the price figure's
   blue so the two numbers on this panel read as one family. */
.pay-price-math {
  padding: var(--sp-6) var(--sp-8);
  background: var(--bg-white);
  border-top: 1px solid var(--border-warm);
}
.pay-price-math-line {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-4);
  margin: 0 0 var(--sp-3);
  text-align: center;
}
.pay-price-math-term {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: var(--fw-bold);
  color: var(--text-main);
}
.pay-price-math-term em {
  font-style: normal;
  color: var(--primary);
}
.pay-price-math-figure {
  font-style: normal;
  font-size: 1.7em;
  font-weight: var(--fw-head);
  line-height: var(--lh-num);
  letter-spacing: -0.02em;
  color: var(--primary);
  margin: 0 0.06em;
}
.pay-price-math-op {
  font-family: var(--font-en);
  font-size: var(--fs-h3);
  font-weight: var(--fw-bold);
  color: var(--accent);
}
.pay-price-math-note {
  margin: 0;
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  color: var(--text-light);
  text-align: center;
  text-wrap: pretty;
}

.pay-price-foot {
  padding: var(--sp-5) var(--sp-8) var(--sp-6);
  background: var(--bg-cream);
  border-top: 1px solid var(--border-warm);
}
.pay-price-foot p {
  margin: 0;
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  color: var(--text-light);
  text-wrap: pretty;
}
.pay-price-foot p + p { margin-top: var(--sp-2); }
.pay-price-foot a {
  color: var(--app-ink-sky);
  font-weight: var(--fw-bold);
  text-decoration: underline;
  text-underline-offset: 3px;
}

@media (max-width: 600px) {
  .pay-price-once { padding: var(--sp-5) var(--sp-5); }
  .pay-price-math { padding: var(--sp-5) var(--sp-5); }
  /* Below 600px the label and the figure stack, so the figure stops being
     the right-hand end of a row and becomes the start of a line. Its gold
     rule follows it: right-aligned under a left-aligned number, the rule
     read as floating loose in the middle of the panel. */
  .pay-price-once-head { flex-basis: 100%; }
  .pay-price-once-figure { align-items: flex-start; }
  .pay-price-table caption { padding: var(--sp-5) var(--sp-5) 0; }
  /* Visually hidden below 600px — the restacked rows carry their own labels.
     Zero its cells too: a clipped 1px box cannot paint, but a 32px-padded
     cell inside it still reports a box wider than the viewport, which is
     noise in any geometry audit. */
  .pay-price-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .pay-price-table thead th { padding: 0; }
  .pay-price-table tbody tr {
    display: block;
    padding: var(--sp-4) var(--sp-5);
    border-bottom: 1px solid var(--border-warm);
  }
  .pay-price-table tbody tr:last-child { border-bottom: 0; }
  .pay-price-table tbody th,
  .pay-price-table tbody td {
    display: block;
    padding: 0;
    border-bottom: 0;
  }
  .pay-price-table tbody th { font-size: var(--fs-h3); line-height: var(--lh-h3); }
  .pay-price-lesson { margin-top: var(--sp-1); font-size: var(--fs-body-sm); }
  .pay-price-fee { margin-top: var(--sp-2); text-align: left; }
  .pay-price-foot { padding: var(--sp-5); }
}


/* ---------------------------------------------------------------------
   2. BRAND CHIPS — the five card brands, set as wordmark-ish pills so
   the row reads at a glance without shipping five logo files (and the
   licensing that comes with them).
--------------------------------------------------------------------- */
.pay-brands {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-5);
  padding: 0;
  list-style: none;
}
.pay-brand {
  display: inline-flex;
  align-items: center;
  padding: var(--sp-1) var(--sp-3);
  border: 1px solid var(--border-warm);
  border-radius: var(--r-sm);
  background: var(--bg-white);
  font-family: var(--font-en);
  font-size: var(--fs-body-sm);
  line-height: 1.4;
  font-weight: var(--fw-bold);
  letter-spacing: 0.02em;
  color: var(--text-main);
  white-space: nowrap;
}


/* ---------------------------------------------------------------------
   3. REASSURANCE CARDS — the four 「安心してよい理由」, built as index.php's
   .about-support-card: blue icon disc and a tilted ghost numeral. The
   method cards this file used to define were retired when section 4 moved
   onto app.css's .app-features, which already ships a richer card with a
   product-shot slot; there is no reason for this page to own a second,
   plainer card of its own.
--------------------------------------------------------------------- */
.pay-safe {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-6);
  margin: 0;
  padding: 0;
  list-style: none;
}
/* index.php's .about-support-card, ported (this page does not load home.css):
   blue icon disc, the rotated ghost numeral top-right, no shadow. It replaces
   a 3px amber left rule that made these four read as the same object as the
   five amber notice boxes the page used to end its sections with. */
.pay-safe-item {
  position: relative;
  overflow: hidden;
  padding: var(--sp-6);
  background: var(--bg-white);
  border: 1px solid var(--border-warm);
  border-radius: var(--r-md);
  min-width: 0;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.pay-safe-item:hover {
  border-color: rgba(0, 174, 239, 0.45);
  box-shadow: var(--shadow-sm);
}
/* home.css:1726 — the tilt is the point: it is the one mark on the card that
   could not have been produced by a layout engine laying out a grid. */
.pay-safe-num {
  position: absolute;
  top: 0.65rem;
  right: 1rem;
  font-size: 2.6rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--accent);
  opacity: 0.18;
  pointer-events: none;
  transform: rotate(-4deg);
}
/* home.css:1741 */
.pay-safe-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 12px;
  background: rgba(0, 174, 239, 0.10);
  color: var(--primary);
  margin-bottom: var(--sp-4);
}
.pay-safe-icon svg { width: 24px; height: 24px; }
.pay-safe-title {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: var(--fw-bold);
  color: var(--text-main);
  text-wrap: balance;
}
.pay-safe-text {
  margin: 0;
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  color: var(--text-light);
  text-wrap: pretty;
}
/* Only the three sides that can afford it shrink on a phone. The left
   padding and the rule's own inset stay at their desktop values, so the
   accent keeps the same clearance from the text at every width.

   This block used to ask for var(--sp-7). The ramp has no --sp-7 (it runs
   1,2,3,4,5,6,8,10,12,14,16,24), and an undefined custom property with no
   fallback makes the WHOLE shorthand invalid at computed-value time — so
   `padding` fell back to its initial value of 0 rather than to the desktop
   rule, dropping the copy flush against the border with the amber rule
   printed on top of it. Every var() on this page is now checked against
   the ramp. */
/* The 2-up grid tightens one step as the columns narrow. It lives HERE,
   below .pay-safe's own rule, and not in the block of whatever component it
   is being kept in step with: at equal specificity the last declaration
   wins, and the first attempt at this sat above .pay-safe's own gap and
   silently lost the cascade. (app.css:890 restacks .app-features to a single
   card per row at this width, so the two grids are no longer comparable —
   the gutters only had to agree while both were multi-column.) */
@media (max-width: 1023px) {
  .pay-safe { gap: var(--sp-5); }
}
@media (max-width: 767px) {
  .pay-safe { grid-template-columns: 1fr; }
  .pay-safe-item { padding: var(--sp-5); }
}


/* ---------------------------------------------------------------------
   5. CALLOUT — ONE per page.
   This shipped five times: at the foot of five consecutive sections, all
   identical, so the page read as heading -> grid -> box, three beats over
   and over, and the box stopped meaning "this one is the exception". Three
   of the five were demoted to app.css's unboxed .app-flow-note, one was
   absorbed into the 安心 sign-off beside the portrait, and this is the
   survivor: the pointer to /tokusho/ and /policy/, which is the only one
   that is a legal caveat rather than a paragraph in a frame.

   Re-cut with no fill, because --bg-warm is also the 入会金 row's ground and
   the rules table's header column — one tint doing three jobs signals none
   of them. It now carries the amber rule that used to run down the side of
   the four 安心 cards, which is where a marked passage belongs.
--------------------------------------------------------------------- */
.pay-callout {
  position: relative;
  max-width: 630px;   /* 42em at this page's 15px body — see 0c above */
  margin: var(--sp-10) auto 0;
  padding: var(--sp-1) 0 var(--sp-1) var(--sp-6);
}
.pay-callout::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  border-radius: var(--r-full);
  background: var(--accent);
}
.pay-callout p {
  margin: 0;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text-main);
  text-wrap: pretty;
}
.pay-callout p + p { margin-top: var(--sp-3); }
.pay-callout em {
  font-style: normal;
  font-weight: var(--fw-bold);
  color: var(--app-ink-amber);
}
.pay-callout a {
  color: var(--app-ink-sky);
  font-weight: var(--fw-bold);
  text-decoration: underline;
  text-underline-offset: 3px;
}


/* ---------------------------------------------------------------------
   6. RULES TABLE — 振替・キャンセル・欠席・退会 against 「請求はどうなるか」.
   The one place on this page where the answer is a rule rather than a
   reassurance, so it is set as a plain two-column table and left to be
   read slowly. Restacks below 600px like .pay-price-table.
--------------------------------------------------------------------- */
.pay-rules {
  max-width: 800px;
  margin: 0 auto;
  background: var(--bg-white);
  border: 1px solid var(--border-warm);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.pay-rules-table {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
}
.pay-rules-table th,
.pay-rules-table td {
  padding: var(--sp-5) var(--sp-8);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  border-bottom: 1px solid var(--border-warm);
  vertical-align: top;
}
.pay-rules-table tbody th {
  /* 30%, the same share legal.css gives its own 事項/内容 table. */
  width: 30%;
  font-weight: var(--fw-bold);
  color: var(--text-main);
  background: var(--bg-warm);
}
.pay-rules-table td { color: var(--text-light); text-wrap: pretty; }
.pay-rules-table tr:last-child th,
.pay-rules-table tr:last-child td { border-bottom: 0; }
.pay-rules-table strong { color: var(--text-main); font-weight: var(--fw-bold); }
@media (max-width: 600px) {
  .pay-rules-table tbody th,
  .pay-rules-table tbody td { display: block; width: auto; padding: var(--sp-4) var(--sp-5); }
  .pay-rules-table tbody th { border-bottom: 0; padding-bottom: var(--sp-2); }
}


/* ---------------------------------------------------------------------
   7. SECTION TWEAKS — the few places this page needs to depart from
   app.css's spacing, plus the narrow-phone floor.
--------------------------------------------------------------------- */
/* The price panel and the rules table are the section's only content, so
   they take the section header's own gap rather than a card grid's. */
.section-pay-price .pay-price,
.section-pay-rules .pay-rules { margin-top: 0; }

/* A caption under a mockup, matching .app-hero-caption's quiet register. */
.pay-shot-caption {
  margin: var(--sp-4) 0 0;
  text-align: center;
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--app-ink-quiet);
}

/* Below 600px the restacked tables carry their padding on the ROW, not the
   cells (the cells are set to 0 there), so tightening the cells here did
   nothing and the panel head pulled 4px left of its own rows. Target what
   actually holds the padding. */
@media (max-width: 360px) {
  .pay-price-table tbody tr,
  .pay-rules-table tbody th,
  .pay-rules-table tbody td { padding-inline: var(--sp-4); }
  .pay-price-table caption { padding-inline: var(--sp-4); }
  .pay-price-once { padding-inline: var(--sp-4); }
  .pay-price-math { padding-inline: var(--sp-4); }
  .pay-price-foot { padding-inline: var(--sp-4); }
}


/* ---------------------------------------------------------------------
   METHOD FEATURE CARDS
   Section 4 borrows /app/'s .app-features (css/app.css:631) — the same
   photo-topped three-up index.php uses for 選ばれる3つの理由, with the
   product shot standing in for the photograph. /app/ opens a detail modal
   from each card, so the component ships cursor:pointer and a hover lift;
   this page has no detail view behind them, so the pointer would promise
   something that does not happen. Keep the frame's hover motion (it reads
   as liveness, not as an affordance) and drop the cursor.
   --------------------------------------------------------------------- */
.pay-features .app-feature { cursor: default; }


/* ---------------------------------------------------------------------
   TWO-UP FLOW
   app.css's .app-flow is a three-across grid because /app/ always has
   three or six steps. 「引き落とされるのは、この2つのタイミングだけ。」 has
   two, and two items in a three-column grid leave a hole on the right that
   reads as a missing card. Narrowing the measure as well as the count is
   deliberate: it stops this section rhyming with the three-across flow in
   「カードが使えなかったときも」, which is the page's most literal repeat.
   --------------------------------------------------------------------- */
.app-flow--two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  max-width: 720px;
  margin-inline: auto;
}
/* app.css restacks .app-flow to one column at 600px, but its rule sits in an
   earlier stylesheet at the same specificity as the modifier above, so the
   modifier would win and hold two columns all the way down. Restate it on the
   site's own breakpoint rather than inventing a step for this one list. */
@media (max-width: 600px) {
  .app-flow--two { grid-template-columns: 1fr; }
}


/* ---------------------------------------------------------------------
   SIGN-OFF — the portrait, and the one paragraph written in first person.
   Ported from index.php's .instructor-portrait (home.css:2341) because this
   page does not load home.css. The polaroid's tilt, the washi tape and the
   handwritten signature are the site's only deliberately imperfect object,
   and the payment page had nothing of the kind anywhere in it: every edge
   was axis-aligned, which is most of why it read as machine-made.

   The credential stamp is left off on purpose. On index.php the stamp is
   the argument (this teacher is qualified); here the caption's job is to
   put a name and a face on the person accountable for the money.
   --------------------------------------------------------------------- */
.pay-signoff {
  display: grid;
  grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
  gap: var(--sp-12);
  align-items: center;
  max-width: 820px;
  margin: var(--sp-14) auto 0;
}
.pay-portrait {
  position: relative;
  margin: 0;
  padding: 0.75rem 0.75rem 3rem;
  background: #fff;
  border: 1px solid var(--border-warm);
  border-radius: 6px;
  box-shadow:
    0 1px 0 rgba(0, 0, 0, 0.04),
    0 18px 38px rgba(35, 25, 15, 0.16);
  transform: rotate(-1.8deg);
}
/* Washi tape, mirrored corners — home.css:2355. Rotated the opposite way
   from index.php's so the two portraits are not the same object twice. */
.pay-portrait::before,
.pay-portrait::after {
  content: '';
  position: absolute;
  width: 100px;
  height: 24px;
  background: linear-gradient(
    180deg,
    rgba(255, 238, 180, 0)    0%,
    rgba(255, 238, 180, 0.5) 14%,
    rgba(253, 230, 160, 0.55) 50%,
    rgba(255, 238, 180, 0.5) 86%,
    rgba(255, 238, 180, 0)  100%
  );
  box-shadow: 0 2px 5px rgba(35, 25, 15, 0.07);
  z-index: 3;
  pointer-events: none;
}
.pay-portrait::before { top: -2px; left: -38px; transform: rotate(-42deg); }
.pay-portrait::after  { bottom: -2px; right: -38px; transform: rotate(-42deg); }
.pay-portrait-frame {
  position: relative;
  border-radius: 3px;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  background: #f3efe9;
}
.pay-portrait-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  filter: saturate(0.95) contrast(0.97);
}
/* The vignette keeps the photo from reading as a flat stock asset dropped
   into a box — home.css:2442. */
.pay-portrait-frame::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 35%, rgba(255, 255, 255, 0) 55%, rgba(35, 25, 15, 0.10) 100%);
  pointer-events: none;
}
.pay-portrait-caption {
  position: absolute;
  left: 0.9rem;
  right: 0.9rem;
  bottom: 0.8rem;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
}
.pay-portrait-sig {
  font-size: 1.65rem;
  font-weight: 700;
  color: var(--primary);
  line-height: 1;
  transform: rotate(-2deg);
  letter-spacing: 0;
}
.pay-portrait-meta {
  font-size: 0.78rem;
  font-weight: var(--fw-bold);
  color: var(--app-ink-quiet);
  letter-spacing: 0.04em;
  text-align: right;
}
.pay-signoff-body p {
  margin: 0;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text-light);
  text-wrap: pretty;
}
.pay-signoff-body p + p { margin-top: var(--sp-3); }
.pay-signoff-body em {
  font-style: normal;
  font-weight: var(--fw-bold);
  color: var(--app-ink-amber);
}
/* The only sentence on the page written in the first person. It is set
   apart so it reads as a person talking, not as another body paragraph. */
.pay-signoff-ask {
  padding-top: var(--sp-4);
  border-top: 1px dashed var(--border-warm);
  color: var(--text-main) !important;
  font-weight: var(--fw-bold);
}
.pay-signoff-ask a {
  color: var(--app-ink-sky);
  text-decoration: underline;
  text-underline-offset: 3px;
}
@media (max-width: 860px) {
  .pay-signoff {
    grid-template-columns: 1fr;
    gap: var(--sp-8);
    justify-items: center;
    max-width: 560px;
  }
  .pay-portrait { max-width: 280px; }
  .pay-signoff-body { text-align: left; }
}


/* ---------------------------------------------------------------------
   GROUND TEXTURE
   index.php lays a gold dot field over two whole sections (home.css:2276
   on 講師紹介, home.css:3198 on 合格までの流れ) so the eye has something to
   rest on between cards. Every ground on this page was a flat fill, which
   is most of why the cream bands read as empty rather than as paper.

   It goes on the two cream bands that sit back to back — 安心のしくみ and
   振替・退会. The band-rhythm note above explains why those two share a
   ground; giving only the second one texture means the seam between them
   is visible without breaking the alternation the rest of the site keeps.
   --------------------------------------------------------------------- */
.page-payment .section-pay-rules {
  position: relative;
  overflow: hidden;
}
.page-payment .section-pay-rules::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, rgba(245, 158, 11, 0.08) 1px, transparent 1.2px);
  background-size: 28px 28px;
  opacity: 0.55;
  pointer-events: none;
}
.page-payment .section-pay-rules > .container { position: relative; }

/* The rules table is the page's other 800px panel and shipped identical to
   the price panel — same radius, same border, same shadow — so the two read
   as twins forty screens apart. The price panel is the one a reader came
   for, so it keeps the deeper shadow (home.css:856's .worries-list tier)
   and this one drops to the flat tier. */
.pay-price { box-shadow: 0 10px 28px rgba(35, 25, 15, 0.07); }
.pay-rules { box-shadow: none; }


/* ---------------------------------------------------------------------
   FAQ CLOSING CARD
   Ported from home.css:3724-3770 (this page does not load home.css).
   index.php ends its FAQ on this card; /payment/ ended on the last
   accordion and dropped straight into the CTA band, which left the page's
   longest and flattest section as its last impression. The -2deg on the
   Caveat heading is the point: it is the second hand-set mark on the page.
   --------------------------------------------------------------------- */
.faq-cta {
  position: relative;
  z-index: 1;
  margin-top: 3.5rem;
  padding: 2.5rem 1.75rem 2.25rem;
  text-align: center;
  background: linear-gradient(135deg, var(--bg-warm) 0%, #fff 70%);
  border: 1px solid var(--border-warm);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
}
.faq-cta-heading {
  display: inline-block;
  font-size: 2rem;
  font-weight: 700;
  color: var(--accent);
  letter-spacing: 0;
  line-height: 1;
  margin-bottom: 0.85rem;
  transform: rotate(-2deg);
}
.faq-cta-text {
  font-size: 0.95rem;
  color: var(--text-main);
  line-height: 1.95;
  margin-bottom: 1.5rem;
}
.faq-cta-text em {
  font-style: normal;
  font-weight: var(--fw-bold);
  color: var(--primary);
  position: relative;
  padding: 0 0.1em;
  z-index: 0;
}
/* Gold ground swatch behind the em — home.css:3760. */
.faq-cta-text em::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0.08em;
  height: 0.3em;
  background: rgba(245, 158, 11, 0.22);
  z-index: -1;
}
.faq-cta-break-mobile { display: none; }
@media (max-width: 768px) {
  .faq-cta { padding: 2rem 1.25rem 1.85rem; margin-top: 2.5rem; }
  .faq-cta-heading { font-size: 1.65rem; }
  .faq-cta-text { font-size: 0.88rem; margin-bottom: 1.25rem; }
  .faq-cta-break-mobile { display: inline; }
}
