/* ==========================================================================
   The Sewing Birdie — Checkout, order received and My Account
   --------------------------------------------------------------------------
   Surface 1  body.tsb-surface-checkout   the block checkout (page 7)
   Surface 2  body.tsb-surface-thanks     the order-received endpoint
   Surface 3  body.tsb-surface-account    My Account (page 8)

   Every value comes from assets/css/tokens.css. Nothing here re-declares a
   colour, a radius, a font or a size.

   WHY THIS FILE CANNOT SIMPLY "STYLE THE BLOCK". The cart and the checkout are
   WooCommerce BLOCK cart/checkout: the server prints an empty skeleton
   (`is-loading` + the nested block wrappers, measured at 52 KB with no field
   markup at all) and React builds the form in the browser. So:

     - anything structural is done by REORDERING what the block already
       rendered (CSS `order`), never by replacing markup;
     - the step titles are React strings, so they are renamed in PHP through
       `gettext` (inc/account/checkout.php);
     - the two strings the blocks render from their own JavaScript bundle
       ("Place Order", "Or continue below") are renamed in JS through
       `wp.hooks.addFilter('i18n.gettext', …)` and, for the button, through the
       live total (assets/js/account.js);
     - the Stripe card element and Stripe's Link button are inside
       CROSS-ORIGIN iframes. Nothing in this stylesheet can reach inside them.

   BEFORE / AFTER measured on the deployed `develop` build (1440 x 900, one
   Libra Dress in the cart): layout shift 0.0169, no H1, breadcrumb present,
   address fields "display:none !important" from functions.php, the required EU
   waiver BELOW the Pay button, and the express buttons last on the page.
   ========================================================================== */

/* ==========================================================================
   0 · TWO LOCAL ALIASES
   --------------------------------------------------------------------------
   assets/css/tokens.css is the single source of truth and is owned by the
   foundation agent, so nothing is added there. The mockups carry exactly two
   colours the shared table does not: the error banner's border (#E3B4B4,
   Checkout.dc.html) and the success tick's fill (#E3ECE6, Thanks.dc.html).
   They are declared once, scoped to these three surfaces, so the values still
   live in one place per surface and cannot leak into the shop pages.
   ========================================================================== */
body.tsb-surface-checkout,
body.tsb-surface-thanks,
body.tsb-surface-account {
  --sb-error-line: #E3B4B4;
  --sb-success-bg: #E3ECE6;
}

/* ==========================================================================
   1 · PAGE FRAME — shared by checkout and order received
   ========================================================================== */

/* The design's checkout column is 1100px, not the 1240px the shop pages use.
   base.css gives #inner-wrap the shop width; --sb-wrap-checkout is the token
   the design system already carries for this. */
body.tsb-surface-checkout #inner-wrap,
body.tsb-surface-thanks #inner-wrap {
  max-width: var(--sb-wrap-checkout);
}

/* No breadcrumb and no Kadence page title inside the checkout funnel. The
   mockup opens with the H1 alone; the theme prints its own H1 (below). */
body.tsb-surface-checkout .kadence-breadcrumbs,
body.tsb-surface-thanks .kadence-breadcrumbs,
body.tsb-surface-checkout .entry-header,
body.tsb-surface-thanks .entry-header,
body.tsb-surface-checkout .kadence-breadcrumbs-wrap,
body.tsb-surface-thanks .kadence-breadcrumbs-wrap {
  display: none;
}

body.tsb-surface-checkout .entry-content,
body.tsb-surface-thanks .entry-content {
  margin-top: 0;
}

/* The whole funnel sits on white: the mockups use #FFFFFF for the page and put
   the warmth in the summary panel instead. --sb-surface, never --sb-bg. */
body.tsb-surface-checkout .site-main,
body.tsb-surface-checkout .content-wrap,
body.tsb-surface-checkout .site,
body.tsb-surface-thanks .site-main,
body.tsb-surface-thanks .content-wrap,
body.tsb-surface-thanks .site {
  background-color: var(--sb-surface);
}

/* --- The page title and its eyebrow ------------------------------------- */
.tsb-checkout-head {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-top: 40px;
}

.tsb-checkout-head .tsb-page-title {
  color: var(--sb-ink);
  font-family: var(--sb-font-display);
  font-size: clamp(2.25rem, 1.6vw + 1.7rem, 2.75rem); /* 36 → 44px */
  font-weight: 400;
  line-height: 1;
  margin: 0;
}

/* The block's own express title, restyled as the mockup's eyebrow. */
body.tsb-surface-checkout .wc-block-components-express-payment__title,
body.tsb-surface-checkout .wc-block-components-express-payment__title-container {
  text-align: left;
}

body.tsb-surface-checkout .wc-block-components-express-payment__title {
  color: var(--sb-muted);
  font-family: var(--sb-font-body);
  font-size: var(--sb-size-caption);
  font-weight: 500;
  letter-spacing: 0.1em;
  margin: 0 0 10px;
  text-transform: uppercase;
}

/* --- Two-column layout -------------------------------------------------- */
body.tsb-surface-checkout .wc-block-components-sidebar-layout {
  gap: 48px;
  padding: 32px 0 80px;
}

body.tsb-surface-checkout .wc-block-components-main {
  flex: 999 1 520px;
  min-width: 0;
  padding-right: 0;
}

body.tsb-surface-checkout .wc-block-components-sidebar {
  flex: 1 1 320px;
  min-width: 0;
  padding: 0;
}

/* ==========================================================================
   2 · THE FORM — order, not markup
   --------------------------------------------------------------------------
   WooCommerce's own DOM order in the form is:
     contact · billing · payment · order-notes · terms · actions · EXPRESS ·
     order-fields(waiver)
   The design's order is:
     EXPRESS · details(contact+billing) · payment · waiver · terms · pay · fine print
   The blocks are React-owned; moving a node would be undone on the next
   re-render, so the form becomes a flex column and every part is ordered with
   `order`. Gaps are stated explicitly because flex disables margin collapsing.
   ========================================================================== */
form.wc-block-components-form.wc-block-checkout__form {
  display: flex;
  flex-direction: column;
  gap: 28px;
}

form.wc-block-components-form.wc-block-checkout__form > * {
  margin: 0;
}

/* The express block: a plain wrapper around the buttons plus the continue rule. */
form.wc-block-components-form.wc-block-checkout__form > div:has(> .wc-block-components-express-payment) {
  order: 0;
}

.wc-block-checkout__contact-fields {
  order: 1;
}

.wc-block-checkout__billing-fields {
  order: 2;
}

.wc-block-checkout__payment-method {
  order: 3;
}

.wc-block-checkout__order-fields {
  order: 4;
}

.wc-block-checkout__terms {
  order: 5;
}

.wc-block-checkout__actions {
  order: 6;
}

/* The design has no order-comments field: every product is a digital download
   and nothing is shipped, so a note to the fulfilment team has nothing to
   reach. Hidden, not removed — WooCommerce still receives the field. A number
   is still declared so it cannot sort itself to the top of the flex column. */
.wc-block-checkout__order-notes {
  display: none !important;
  order: 7;
}

/* --- Step headings ------------------------------------------------------ */
body.tsb-surface-checkout .wc-block-components-checkout-step__title {
  color: var(--sb-ink);
  font-family: var(--sb-font-body);
  font-size: 1.125rem; /* 18px, the mockup's legend */
  font-weight: 600;
  line-height: 1.3;
}

/* The billing step carries first name, last name and country, which the design
   presents inside the SAME "Your details" block as the email field, so its own
   heading and its address card are not printed. */
body.tsb-surface-checkout .wc-block-checkout__billing-fields .wc-block-components-checkout-step__heading-container,
body.tsb-surface-checkout .wc-block-checkout__billing-fields .wc-block-components-address-card-wrapper {
  display: none;
}

/* The EU digital-content waiver is a required checkbox. The design has no
   heading for it: it belongs with the payment block, directly above the pay
   button. Its step heading is therefore not printed (the checkbox carries its
   own label). */
body.tsb-surface-checkout .wc-block-checkout__order-fields .wc-block-components-checkout-step__heading-container {
  display: none;
}

body.tsb-surface-checkout .wc-block-components-checkout-step__heading {
  margin-bottom: 14px;
}

/* --- Fields -------------------------------------------------------------
   functions.php hides the WHOLE billing step and the whole billing address
   with `display:none !important` because nothing in this shop ships. That rule
   is `.wc-block-checkout__billing-fields` (specificity 0,1,0), so the step has
   to be switched back on before the fields inside it can be seen at all — a
   `display` on the field itself would do nothing while its ancestor is
   `display:none`. The design keeps THREE of those fields — first name, last
   name and country (country is what VAT is assessed on) — so exactly those
   three are switched on too. The address, city, county, postcode, company,
   phone and the "apartment, suite, etc." toggle stay hidden.
   ------------------------------------------------------------------------ */
body.tsb-surface-checkout .wc-block-checkout__billing-fields,
body.tsb-surface-checkout .wc-block-components-address-form__first_name,
body.tsb-surface-checkout .wc-block-components-address-form__last_name,
body.tsb-surface-checkout .wc-block-components-address-form__country {
  display: block !important;
}

body.tsb-surface-checkout .wc-block-components-address-form__address_2-toggle,
body.tsb-surface-checkout .wc-block-components-address-form__address_2-hidden-input {
  display: none !important;
}

/* The combined "Your name" additional field is replaced by the two real name
   fields. inc/account/checkout.php fills the value it feeds the order from
   those two fields, so nothing downstream changes. */
body.tsb-surface-checkout .wc-block-components-address-form__thesewingbirdie-full-name {
  display: none !important;
}

/* The mockup's "Email — your download links go here" makes the purpose clear;
   WooCommerce's own label is just "Email address". The hint is printed once,
   under the field, from inc/account/checkout.php — and it is the same sentence
   in the label's `aria-describedby`, so screen readers hear it too. */
body.tsb-surface-checkout .wc-block-components-address-form__email {
  margin-bottom: 4px;
}

body.tsb-surface-checkout .wc-block-components-address-form__country .wc-block-components-country-input__label,
body.tsb-surface-checkout .wc-block-components-address-form__country label {
  color: var(--sb-ink);
  font-size: var(--sb-size-small);
  font-weight: 500;
}

/* Every visible label in the funnel: same size and weight as the mockup. */
body.tsb-surface-checkout .wc-block-components-text-input label,
body.tsb-surface-checkout .wc-block-components-select label,
body.tsb-surface-checkout .wc-block-components-radio-control__option label {
  color: var(--sb-ink);
  font-size: var(--sb-size-small);
  font-weight: 500;
}

/* The country select keeps the token border and the 48px target. The extra
   20px of top padding is what keeps WooCommerce's FLOATING label ("Country for
   VAT") above the value instead of on top of it — measured at 1440px: with
   `padding: 0 12px` the label and "Romania" were drawn over one another. */
body.tsb-surface-checkout .wc-block-components-address-form__country select {
  background-color: var(--sb-surface);
  border: 1px solid var(--sb-line-input);
  border-radius: var(--sb-r-btn);
  color: var(--sb-ink);
  font-family: var(--sb-font-body);
  font-size: 1rem;
  min-height: 56px;
  padding: 20px 12px 4px;
  width: 100%;
}

/* Guest checkout notice: the mockup replaces WooCommerce's bare sentence with
   the reason the customer can keep going. Wording is set in
   inc/account/checkout.php; this only spaces it. */
body.tsb-surface-checkout .wc-block-checkout__guest-checkout-notice {
  color: var(--sb-muted);
  font-size: var(--sb-size-caption);
  margin: 6px 0 0;
}

/* --- Express checkout --------------------------------------------------- */
body.tsb-surface-checkout .wc-block-components-express-payment {
  border: 0;
  margin: 0;
  padding: 0;
}

body.tsb-surface-checkout .wc-block-components-express-payment__event-buttons {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* One button (Link alone, or a single wallet) fills the row; two split it. */
body.tsb-surface-checkout .wc-block-components-express-payment__event-buttons > *:only-child {
  grid-column: 1 / -1;
}

body.tsb-surface-checkout .wc-block-components-express-payment__event-buttons > * {
  min-height: 48px;
}

/* The `--checkout` express block renders its own "Or continue below" rule. The
   text is replaced through i18n.gettext in assets/js/account.js; this draws the
   mockup's rule around it. */
body.tsb-surface-checkout .wc-block-components-express-payment-continue-rule {
  align-items: center;
  color: var(--sb-muted);
  display: flex;
  font-size: var(--sb-size-small);
  gap: 12px;
  margin: 22px 0 0;
  text-align: center;
}

body.tsb-surface-checkout .wc-block-components-express-payment-continue-rule::before,
body.tsb-surface-checkout .wc-block-components-express-payment-continue-rule::after {
  background-color: var(--sb-line);
  content: '';
  flex: 1;
  height: 1px;
}

/* --- Payment methods ---------------------------------------------------- */
body.tsb-surface-checkout .wc-block-components-radio-control__option {
  padding-left: 0;
}

body.tsb-surface-checkout .wc-block-components-radio-control__option-layout {
  border-color: var(--sb-line-input);
  border-radius: var(--sb-r-btn);
  padding: 14px 16px;
}

body.tsb-surface-checkout .wc-block-components-radio-control--highlight-checked .wc-block-components-radio-control__option-checked {
  background-color: var(--sb-surface);
}

/* The Stripe card iframe is cross-origin; only its BOX is ours to set. */
body.tsb-surface-checkout .wc-block-components-radio-control__option-layout > div > div {
  min-height: 44px;
}

/* The mockup's reassurance line under the card field. */
.tsb-card-note {
  color: var(--sb-muted);
  font-size: var(--sb-size-caption);
  margin: 12px 0 0;
}

/* ==========================================================================
   3 · THE ERROR BANNER
   --------------------------------------------------------------------------
   The block renders payment failures as
     <div class="wc-block-store-notice wc-block-components-notice-banner is-error">
       <svg/><div class="…__content">
         <p class="…__summary">Please fix the following error before continuing</p>
         <ul class="…__list"><li><div>TEXT</div></li></ul>
       </div><button class="…__dismiss"></button></div>
   — measured on a real 4000 0000 0000 0002 decline, staging, 15 Oct 2026.
   It carries NO role="alert", and its message reads "There was an error
   processing the payment: The card was declined.". assets/js/account.js adds
   role="alert" and rewrites the list item's message into the design's wording,
   and this block hides the redundant "Please fix…" summary and paints the
   design's --sb-error-bg / --sb-error-fg pair.
   The rewrite mutates the existing text node in place; see setTextInPlace() in
   assets/js/account.js for why the notice's nodes must not be replaced.
   ========================================================================== */
body.tsb-surface-checkout .wc-block-components-notice-banner.is-error {
  align-items: flex-start;
  background-color: var(--sb-error-bg);
  border: 1px solid var(--sb-error-line);
  border-radius: var(--sb-r-btn);
  color: var(--sb-error-fg);
  font-size: var(--sb-size-small);
  gap: 12px;
  margin: 0 0 16px;
  padding: 14px 16px;
}

body.tsb-surface-checkout .wc-block-components-notice-banner.is-error svg {
  color: var(--sb-error-fg);
  fill: var(--sb-error-fg);
}

body.tsb-surface-checkout .wc-block-components-notice-banner.is-error .wc-block-components-notice-banner__summary {
  font-weight: 700;
  margin: 0;
}

body.tsb-surface-checkout .wc-block-components-notice-banner.is-error .wc-block-components-notice-banner__list li {
  font-weight: 400;
}

/* The design's banner is one sentence, not a heading plus a list. The JS
   rewrites the list item's text in place (never rebuilding the notice's
   children: those nodes belong to React). */
body.tsb-surface-checkout .wc-block-components-notice-banner.tsb-payment-error .wc-block-components-notice-banner__summary {
  display: none;
}

body.tsb-surface-checkout .wc-block-components-notice-banner.is-error .wc-block-components-notice-banner__dismiss {
  color: var(--sb-error-fg);
  min-height: 24px;
  min-width: 24px;
}

/* Field-level validation messages (the waiver, the email) keep the same
   palette but stay inline and quiet. */
body.tsb-surface-checkout .wc-block-components-validation-error p {
  color: var(--sb-error-fg);
  font-size: var(--sb-size-caption);
}

body.tsb-surface-checkout .wc-block-components-validation-error svg {
  fill: var(--sb-error-fg);
}

/* ==========================================================================
   4 · CONSENT, TERMS AND THE PAY BUTTON
   ========================================================================== */
body.tsb-surface-checkout .wc-block-components-checkbox__label,
body.tsb-surface-checkout .wc-block-components-checkbox label {
  color: var(--sb-ink-2);
  font-size: var(--sb-size-small);
  line-height: 1.5;
}

body.tsb-surface-checkout .wc-block-checkout__terms {
  border: 0;
  color: var(--sb-muted);
  font-size: var(--sb-size-caption);
  margin: 0;
  padding: 0;
}

body.tsb-surface-checkout .wc-block-checkout__terms a {
  color: var(--sb-muted);
}

/* The mockup's pay button is a 56px block. */
body.tsb-surface-checkout .wc-block-components-checkout-place-order-button {
  font-size: 1.0625rem; /* 17px */
  min-height: 56px;
  width: 100%;
}

/* The mockup's fine print, printed under the button by
   inc/account/checkout.php. */
.tsb-checkout-fineprint {
  color: var(--sb-muted);
  font-size: var(--sb-size-caption);
  line-height: 1.55;
  margin: 0;
}

.tsb-checkout-fineprint a {
  color: var(--sb-muted);
}

body.tsb-surface-checkout .wc-block-checkout__actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* ==========================================================================
   5 · ORDER SUMMARY PANEL
   ========================================================================== */
body.tsb-surface-checkout .wc-block-components-checkout-order-summary__title {
  border: 0;
  margin-bottom: 14px;
}

body.tsb-surface-checkout .wc-block-components-checkout-order-summary__title-text {
  color: var(--sb-ink);
  font-size: 1.125rem;
  font-weight: 600;
}

/* The panel itself: the design puts the summary on --sb-soft with an 8px
   radius. WooCommerce renders the block inside `.wc-block-checkout__sidebar`,
   so the panel is the sidebar — and the mobile toggle stays inside it. */
@media (min-width: 1000px) {
  body.tsb-surface-checkout .wc-block-checkout__sidebar {
    background-color: var(--sb-soft);
    border-radius: var(--sb-r-band);
    padding: 28px;
  }
}

@media (max-width: 999px) {
  body.tsb-surface-checkout .wc-block-checkout__sidebar {
    border: 1px solid var(--sb-line);
    border-radius: var(--sb-r-band);
    margin-bottom: 24px;
    padding: 0 16px;
  }
}

/* The mockup's line item is a 56px 4:5 thumbnail, the name and one short meta
   line. The block prints the product's whole SHORT DESCRIPTION under the name
   ("What you get: • Yours the moment you pay — download it, print it, sew it.")
   which turns a three-line row into a ten-line one, so that paragraph is not
   printed here. The name and the price are all the customer needs to check the
   order, and the full description is one click away on the product page. */
body.tsb-surface-checkout .wc-block-components-order-summary-item {
  gap: 14px;
}

body.tsb-surface-checkout .wc-block-components-order-summary-item__image {
  flex: none;
  width: 56px;
}

body.tsb-surface-checkout .wc-block-components-order-summary-item__image img {
  aspect-ratio: 4 / 5;
  border-radius: var(--sb-r-img);
  object-fit: cover;
  width: 56px;
}

body.tsb-surface-checkout .wc-block-components-order-summary-item__description {
  font-size: 0.9375rem; /* 15px */
  min-width: 0;
}

body.tsb-surface-checkout .wc-block-components-order-summary-item__description p {
  display: none;
}

body.tsb-surface-checkout .wc-block-components-order-summary-item__total-price {
  font-weight: 600;
  white-space: nowrap;
}

body.tsb-surface-checkout .wc-block-components-totals-item {
  font-size: 0.9375rem;
}

body.tsb-surface-checkout .wc-block-components-totals-footer-item {
  border-top: 1px solid var(--sb-line);
  font-size: 1.25rem; /* 20px */
  font-weight: 600;
  margin-top: 14px;
  padding-top: 14px;
}

body.tsb-surface-checkout .wc-block-components-totals-footer-item .wc-block-components-totals-item__label,
body.tsb-surface-checkout .wc-block-components-totals-footer-item .wc-block-formatted-money-amount {
  font-weight: 600;
}

/* The mockup's three reassurance lines. assets/js/account.js appends them to the
   END of the summary panel — the last element in the sidebar column, so on
   desktop nothing that is already on screen moves. Below 1000px the summary
   stacks ABOVE the form, where three extra lines would push the whole form
   down and cost layout shift, so they are not shown there (the mockup's mobile
   summary is the collapsed one anyway). */
.tsb-summary-trust {
  border-top: 1px solid var(--sb-line);
  color: var(--sb-ink-2);
  display: none;
  flex-direction: column;
  gap: 8px;
  font-size: var(--sb-size-small);
  list-style: none;
  margin: 14px 0 0;
  padding: 14px 0 0;
}

@media (min-width: 1000px) {
  .tsb-summary-trust {
    display: flex;
  }
}

.tsb-summary-trust li::before {
  color: var(--sb-success);
  content: '✓  ';
  font-weight: 700;
}

/* --- Mobile: the summary comes first and collapses ---------------------- */
@media (max-width: 999px) {
  body.tsb-surface-checkout .wc-block-components-sidebar-layout {
    gap: 0;
    padding: 20px 0 56px;
  }

  body.tsb-surface-checkout .wc-block-components-sidebar {
    flex: 1 1 100%;
    order: -1;
  }

  form.wc-block-components-form.wc-block-checkout__form {
    gap: 24px;
  }

  body.tsb-surface-checkout .wc-block-components-express-payment__event-buttons {
    grid-template-columns: 1fr;
  }
}

/* ==========================================================================
   6 · ORDER RECEIVED (Thanks.dc.html)
   ========================================================================== */
body.tsb-surface-thanks .tsb-thanks {
  display: flex;
  flex-direction: column;
  gap: 40px;
  padding: 48px 0 80px;
}

/* Thanks.dc.html puts "My pattern library →" in the minimal header
   (template-parts/header/minimal.php). This content-row copy was a duplicate on
   the same page and has been removed — QA round 4, D8. */

.tsb-thanks__intro {
  align-items: flex-start;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.tsb-thanks__tick {
  align-items: center;
  background-color: var(--sb-success-bg);
  border-radius: var(--sb-r-chip);
  display: flex;
  height: 56px;
  justify-content: center;
  width: 56px;
}

.tsb-thanks__title {
  color: var(--sb-ink);
  font-family: var(--sb-font-display);
  font-size: clamp(2.375rem, 3vw + 1.4rem, 3.5rem); /* 38 → 56px */
  font-weight: 400;
  line-height: 1;
  margin: 0;
}

.tsb-thanks__lead {
  color: var(--sb-ink-2);
  font-size: 1.125rem;
  margin: 0;
}

.tsb-thanks__cols {
  align-items: flex-start;
  display: flex;
  flex-wrap: wrap;
  gap: 40px;
}

.tsb-thanks__downloads {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}

.tsb-thanks__h2 {
  color: var(--sb-ink);
  font-family: var(--sb-font-display);
  font-size: 2.125rem; /* 34px */
  font-weight: 400;
  line-height: 1.1;
  margin: 0;
}

.tsb-download-card {
  border: 1px solid var(--sb-line);
  border-radius: var(--sb-r-band);
  display: flex;
  gap: 18px;
  padding: 18px;
}

.tsb-download-card__thumb {
  /* `align-self`/`height` are load-bearing: the card is a flex row, whose
     default `align-items: stretch` would stretch the image to the card's height
     and defeat `aspect-ratio` — the exact bug QA measured on the My patterns
     thumbnails (D7). */
  align-self: flex-start;
  aspect-ratio: 4 / 5;
  background-color: var(--sb-photo);
  border-radius: var(--sb-r-img);
  flex: none;
  height: auto;
  object-fit: cover;
  width: 96px;
}

.tsb-download-card__sewalong {
  font-size: var(--sb-size-small);
  font-weight: 600;
}

.tsb-download-card__body {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.tsb-download-card__name {
  font-size: 1.0625rem;
  font-weight: 600;
}

.tsb-download-card__files {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tsb-file-btn {
  align-items: center;
  border: 1px solid var(--sb-ink);
  border-radius: var(--sb-r-btn);
  color: var(--sb-ink);
  display: inline-flex;
  font-size: var(--sb-size-small);
  font-weight: 600;
  min-height: 44px;
  padding: 0 14px;
  text-decoration: none;
}

.tsb-file-btn--primary {
  background-color: var(--sb-ink);
  color: var(--sb-surface);
}

.tsb-file-btn--primary:hover,
.tsb-file-btn--primary:focus {
  background-color: var(--sb-ink-2);
  color: var(--sb-surface);
}

.tsb-file-btn:hover,
.tsb-file-btn:focus {
  background-color: var(--sb-soft);
  color: var(--sb-ink);
}

/* "Keep your patterns forever" — the set-password panel. */
.tsb-keep {
  background-color: var(--sb-soft);
  border-radius: var(--sb-r-band);
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 24px;
}

.tsb-keep__title {
  font-weight: 600;
}

.tsb-keep__copy {
  color: var(--sb-ink-2);
  font-size: var(--sb-size-small);
  margin: 0;
}

.tsb-keep__row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.tsb-keep__row input {
  flex: 1 1 220px;
  min-height: 46px;
}

.tsb-keep__row .tsb-btn {
  min-height: 46px;
}

.tsb-keep__form {
  margin: 0;
}

.tsb-keep__error {
  color: var(--sb-error-fg);
  font-size: var(--sb-size-small);
  margin: 0;
}

.tsb-keep__note {
  color: var(--sb-muted);
  font-size: var(--sb-size-caption);
  margin: 0;
}

/* Receipt panel. */
.tsb-receipt {
  border: 1px solid var(--sb-line);
  border-radius: var(--sb-r-band);
  display: flex;
  flex: 1 1 320px;
  flex-direction: column;
  gap: 12px;
  font-size: 0.9375rem;
  min-width: 0;
  padding: 24px;
}

.tsb-receipt__title {
  font-size: 1.125rem;
  font-weight: 600;
  margin: 0;
}

.tsb-receipt__row {
  display: flex;
  gap: 12px;
  justify-content: space-between;
}

.tsb-receipt__meta {
  color: var(--sb-muted);
}

.tsb-receipt__total {
  border-top: 1px solid var(--sb-line);
  font-size: 1.125rem;
  font-weight: 600;
  padding-top: 12px;
}

/* The receipt's invoice line — Thanks.dc.html's last row in the Receipt panel
   ("Download invoice (PDF)", 14px). The URL, the access key and the permission
   checks all come from `woocommerce-pdf-invoices-packing-slips`' own
   `[wcpdf_document_link]` shortcode (inc/account/invoice.php); this styles the
   anchor it produced and nothing else. `min-height` is the shared touch target
   (shared context §4) — the visible text stays at the mockup's 14px. */
.tsb-thanks__invoice {
  margin: 0;
}

.tsb-invoice-link {
  align-items: center;
  color: var(--sb-ink);
  display: inline-flex;
  font-size: 0.875rem;
  font-weight: 600;
  min-height: 44px;
}

.tsb-invoice-link:hover,
.tsb-invoice-link:focus {
  color: var(--sb-accent-hover);
}

.tsb-next {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.tsb-next__grid {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.tsb-next__card {
  border: 1px solid var(--sb-line);
  border-radius: var(--sb-r-band);
  color: var(--sb-ink);
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 22px;
  text-decoration: none;
}

.tsb-next__card:hover,
.tsb-next__card:focus {
  background-color: var(--sb-soft);
  color: var(--sb-ink);
}

.tsb-next__card span:last-child {
  color: var(--sb-muted);
  font-size: var(--sb-size-small);
}

@media (max-width: 767px) {
  body.tsb-surface-thanks .tsb-thanks {
    padding-top: 32px;
  }

  .tsb-download-card {
    flex-direction: column;
  }

  .tsb-download-card__thumb {
    width: 100%;
  }
}

/* ==========================================================================
   7 · MY ACCOUNT (Account.dc.html)
   ========================================================================== */
body.tsb-surface-account .site-main {
  background-color: var(--sb-surface);
}

/* Undo Kadence's floated account sidebar.
   --
   The parent theme wraps `woocommerce_account_navigation` in
   `.account-navigation-wrap` and, from 768px up, floats it right at 30% with the
   content floated left at 70% (themes/kadence/assets/css/woocommerce-account.min.css).
   Account.dc.html is ONE column: banner → H1 + Log out → full-width tablist →
   panel. Measured on the floated layout (QA round 4, D6): content column
   x168–941, `.account-navigation-wrap` x941–1272 — a 331px sidebar, a 0px gutter,
   the H1 wrapping to two lines inside it, and "Account details" pushed onto a
   second tab row. Both floats are removed here, so the nav sits above the
   content at full width as the mockup shows. */
body.tsb-surface-account .account-navigation-wrap {
  border-left: 0;
  float: none;
  margin-bottom: 0;
  width: auto;
}

body.tsb-surface-account.kadence-account-nav-left .account-navigation-wrap {
  border-right: 0;
  float: none;
}

body.tsb-surface-account .kadence-breadcrumbs,
body.tsb-surface-account .entry-header {
  display: none;
}

.tsb-account {
  margin: 0 auto;
  max-width: var(--sb-wrap);
  padding: 40px 0 0;
}

/* --- Fresh-order banner -------------------------------------------------- */
.tsb-account__banner {
  align-items: center;
  background-color: var(--sb-chip);
  border-radius: var(--sb-r-band);
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: space-between;
  padding: 18px 22px;
}

.tsb-account__banner span:first-child {
  font-weight: 500;
}

.tsb-account__banner span:last-child {
  color: var(--sb-muted);
  font-size: var(--sb-size-small);
}

/* --- Greeting ------------------------------------------------------------ */
.tsb-account__top {
  align-items: flex-end;
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  justify-content: space-between;
  margin-top: 36px;
}

.tsb-account__greeting {
  color: var(--sb-ink);
  font-family: var(--sb-font-display);
  font-size: clamp(2.375rem, 3vw + 1.4rem, 3.5rem);
  font-weight: 400;
  line-height: 1;
  margin: 0;
}

.tsb-account__logout {
  color: var(--sb-muted);
  font-size: var(--sb-size-small);
}

/* --- Tabs (the mockup's tablist, not WooCommerce's sidebar nav) ---------- */
.tsb-account__tabs {
  border-bottom: 1px solid var(--sb-line);
  display: flex;
  flex-wrap: wrap;
  gap: 4px 28px;
  margin-top: 28px;
}

.tsb-account__tab {
  align-items: center;
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  color: var(--sb-muted);
  display: inline-flex;
  font-family: var(--sb-font-body);
  font-size: 1rem;
  font-weight: 500;
  margin-bottom: -1px;
  min-height: 48px;
  padding: 0;
  text-decoration: none;
}

.tsb-account__tab:hover,
.tsb-account__tab:focus {
  color: var(--sb-ink);
}

.tsb-account__tab[aria-current='page'],
.tsb-account__tab.is-current {
  border-bottom-color: var(--sb-ink);
  color: var(--sb-ink);
  font-weight: 600;
}

/* WooCommerce still renders its own navigation for non-JS and for the
   endpoints' markup contracts; it is replaced by the tablist above. */
body.tsb-surface-account .woocommerce-MyAccount-navigation {
  display: none;
}

body.tsb-surface-account .woocommerce-MyAccount-content {
  float: none;
  padding-left: 0;
  padding-right: 0;
  padding-top: 32px;
  width: auto;
}

body.tsb-surface-account .woocommerce-MyAccount-content p:first-child {
  margin-top: 0;
}

/* --- My patterns: the library grid --------------------------------------- */
.tsb-library {
  display: grid;
  gap: 24px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}

.tsb-pattern {
  border: 1px solid var(--sb-line);
  border-radius: var(--sb-r-band);
  display: flex;
  gap: 16px;
  padding: 16px;
}

.tsb-pattern__thumb {
  /* `align-self`/`height` are load-bearing. `.tsb-pattern` is a flex row, whose
     default `align-items: stretch` stretched this image to the card's height, so
     a 96px-wide thumb rendered 96×198.5 — ratio 0.484 instead of the design's
     0.800 (QA round 4, D7). With the stretch removed, `aspect-ratio: 4/5` wins
     and the thumb is 96×120. */
  align-self: flex-start;
  aspect-ratio: 4 / 5;
  background-color: var(--sb-photo);
  border-radius: var(--sb-r-img);
  flex: none;
  height: auto;
  object-fit: cover;
  width: 96px;
}

.tsb-pattern__body {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

.tsb-pattern__name {
  font-weight: 600;
}

.tsb-pattern__when {
  color: var(--sb-muted);
  font-size: var(--sb-size-caption);
}

.tsb-pattern__files {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 2px;
}

.tsb-pattern__files .tsb-file-btn {
  font-size: var(--sb-size-caption);
  min-height: 36px;
  padding: 0 12px;
}

.tsb-pattern__sewalong {
  font-size: var(--sb-size-small);
  font-weight: 600;
}

.tsb-library-empty {
  color: var(--sb-ink-2);
}

/* --- My courses ---------------------------------------------------------- */
.tsb-course {
  align-items: center;
  border: 1px solid var(--sb-line);
  border-radius: var(--sb-r-band);
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  padding: 20px;
}

.tsb-course__thumb {
  aspect-ratio: 16 / 10;
  background-color: var(--sb-photo);
  border-radius: var(--sb-r-img);
  flex: none;
  object-fit: cover;
  width: 200px;
}

.tsb-course__body {
  display: flex;
  flex: 1 1 320px;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.tsb-course__name {
  color: var(--sb-ink);
  font-family: var(--sb-font-display);
  font-size: 1.75rem;
  line-height: 1.1;
  margin: 0;
}

.tsb-course__bar {
  background-color: var(--sb-photo);
  border-radius: var(--sb-r-chip);
  height: 8px;
  overflow: hidden;
}

.tsb-course__bar span {
  background-color: var(--sb-accent-strong);
  display: block;
  height: 100%;
}

.tsb-course__meta {
  color: var(--sb-muted);
  font-size: var(--sb-size-small);
}

.tsb-course__cta {
  align-items: center;
  background-color: var(--sb-accent-strong);
  border-radius: var(--sb-r-btn);
  color: var(--sb-surface);
  display: inline-flex;
  font-weight: 600;
  min-height: 48px;
  padding: 0 22px;
  text-decoration: none;
}

.tsb-course__cta:hover,
.tsb-course__cta:focus {
  background-color: var(--sb-accent-hover);
  color: var(--sb-surface);
}

/* --- Orders: a table that scrolls on phones ------------------------------ */
.tsb-orders {
  overflow-x: auto;
}

.tsb-orders table {
  border-collapse: collapse;
  font-size: 0.9375rem;
  min-width: 560px;
  width: 100%;
}

.tsb-orders th {
  color: var(--sb-muted);
  font-size: var(--sb-size-caption);
  font-weight: 500;
  padding: 10px 8px;
  text-align: left;
}

.tsb-orders td {
  border-top: 1px solid var(--sb-line);
  padding: 14px 8px;
  vertical-align: middle;
}

/* WooCommerce's own downloads table and orders table, for the cases where its
   template wins (a plugin-added column, a filtered hook); both are restyled so
   the page never falls back to the parent theme's look. */
body.tsb-surface-account .woocommerce-table--order-downloads,
body.tsb-surface-account .woocommerce-orders-table {
  border-collapse: collapse;
  font-size: 0.9375rem;
  width: 100%;
}

body.tsb-surface-account .woocommerce-table--order-downloads th,
body.tsb-surface-account .woocommerce-orders-table th {
  color: var(--sb-muted);
  font-size: var(--sb-size-caption);
  font-weight: 500;
  padding: 10px 8px;
  text-align: left;
}

body.tsb-surface-account .woocommerce-table--order-downloads td,
body.tsb-surface-account .woocommerce-orders-table td {
  border-top: 1px solid var(--sb-line);
  padding: 14px 8px;
}

body.tsb-surface-account .woocommerce-button,
body.tsb-surface-account .woocommerce-Button {
  align-items: center;
  background-color: var(--sb-ink);
  border: 1px solid var(--sb-ink);
  border-radius: var(--sb-r-btn);
  color: var(--sb-surface);
  display: inline-flex;
  font-weight: 600;
  min-height: 44px;
  padding: 0 16px;
  text-decoration: none;
}

/* --- Account details ---------------------------------------------------- */
body.tsb-surface-account .woocommerce-EditAccountForm {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 520px;
}

body.tsb-surface-account .woocommerce-EditAccountForm label {
  color: var(--sb-ink);
  display: flex;
  flex-direction: column;
  font-size: var(--sb-size-small);
  font-weight: 500;
  gap: 6px;
}

body.tsb-surface-account .woocommerce-EditAccountForm fieldset {
  border: 0;
  margin: 0;
  padding: 0;
}

body.tsb-surface-account .woocommerce-EditAccountForm .woocommerce-Button {
  align-self: flex-start;
  min-height: 48px;
  padding: 0 22px;
}

/* --- "Printing for the first time?" ------------------------------------- */
.tsb-account__help {
  align-items: center;
  background-color: var(--sb-soft);
  border-radius: var(--sb-r-band);
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  justify-content: space-between;
  margin: 64px 0 80px;
  padding: 32px;
}

.tsb-account__help-title {
  color: var(--sb-ink);
  display: block;
  font-family: var(--sb-font-display);
  font-size: 1.75rem;
  line-height: 1.1;
}

.tsb-account__help p {
  color: var(--sb-ink-2);
  font-size: var(--sb-size-small);
  margin: 6px 0 0;
}

@media (max-width: 767px) {
  .tsb-account {
    padding-top: 24px;
  }

  .tsb-library {
    grid-template-columns: 1fr;
  }

  .tsb-course {
    flex-direction: column;
    align-items: flex-start;
  }

  .tsb-course__thumb {
    width: 100%;
  }
}

/* ==========================================================================
   8 · CURRENCY SWITCHER (header)
   --------------------------------------------------------------------------
   Rendered by inc/account/currency.php ONLY when a currency-switching plugin
   is active that this theme has been told to support. Until then the function
   returns nothing and this rule has no element to match — the switcher cannot
   show a currency the shop cannot charge in. See inc/account/currency.php for
   the recommendation and the trade-offs.
   ========================================================================== */
.tsb-currency {
  align-items: center;
  display: flex;
}

.tsb-currency label {
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

.tsb-currency select {
  background-color: var(--sb-surface);
  border: 1px solid var(--sb-line);
  border-radius: var(--sb-r-btn);
  color: var(--sb-ink);
  font-family: var(--sb-font-body);
  font-size: var(--sb-size-small);
  min-height: 40px;
  padding: 8px 10px;
}
