/**
 * Shared styling for the gift table as it appears on the shopping cart, the
 * checkout Order information step and the checkout Review step.
 *
 * One file rather than one per page, deliberately: the whole point is that the
 * three pages look like the same page, and the earlier arrangement of a
 * separate stylesheet per context is exactly how the quality-flag styling
 * ended up duplicated and drifting.
 *
 * Loaded by:
 *  - thingsloved_order_form_alter()  (the cart form)
 *  - OrderDetail checkout pane       (order information + review)
 */

/* ---------------------------------------------------------------------------
 * The ground both pages stand on
 *
 * The same #ced1cd as /create-photo, /create-keepsake and My Keepsakes, so the
 * whole journey — build a gift, look at the cart, pay for it — is one room
 * rather than four.
 *
 * Stated on the BODY, and only here. The two builders paint their own ground by
 * breaking a full-width wrapper out of the theme's content container, because
 * their app IS the page; the cart and the checkout are ordinary pages with a
 * heading above them, and a wrapper would leave that heading standing on white.
 * Everything between these pages and the browser's own canvas is transparent on
 * this theme — html, body, .wrap-containers, .main-container, .region-content
 * and the content block were each checked — so one declaration colours the lot.
 * ------------------------------------------------------------------------ */
body.path-cart,
body.path-checkout {
  background-color: #ced1cd;
}

/* ---------------------------------------------------------------------------
 * Content width
 *
 * The theme caps .main-container at 960px, which leaves the gift table about
 * 840px — cramped once a photo column is in it. Both pages are lifted off that
 * cap here; max-width, not width, so narrower screens are unaffected.
 *
 * The cart and the checkout share a LAYOUT — an order panel with a summary
 * panel beside it — but deliberately not a width. What each panel holds is not
 * the same thing: the cart's is a table, which is content-shaped and stops
 * needing room at a point, while the checkout's holds forms, which want every
 * pixel they can get. Tying the two figures together forces one page to live
 * with a number chosen for the other, so each states its own: the cart's is in
 * gift-table.css, the checkout's is below.
 * ------------------------------------------------------------------------ */
body.path-cart .main-container.container,
body.path-checkout .main-container.container {
  max-width: 1320px;
}

/* Free to move without touching the cart.
   Widened to match it on 2026-08-30 for the same reason — the gift cards are
   the same cards and their variant lines were running out of room. Checkout had
   more to spare (512px against the 462 the longest line needs) because its
   summary panel is narrower, so this is the smaller of the two changes; it
   lands on the same figure because one number is easier to keep true than
   two. */
body.path-checkout .main-container.container {
  max-width: 1492px;
}

/* ---------------------------------------------------------------------------
 * The customer's photo
 *
 * Identical rendered size on all three pages. The column needs a reserved
 * width: the theme's .img-fluid rule (max-width: 100%) shrinks the image
 * whenever its cell is tight, and the cart carries two columns the checkout
 * table does not (Quantity, Remove), so the very same image rendered smaller
 * there than at checkout.
 *
 * Size is capped, never forced, so the approved crop keeps its true aspect
 * ratio — the shape is what tells a 4x6 apart from an 8x10.
 * ------------------------------------------------------------------------ */
.view-commerce-cart-form .views-field-field-cropped-photo,
.tl-order-detail .views-field-field-cropped-photo {
  width: 240px;
}

.view-commerce-cart-form .views-field-field-cropped-photo img,
.tl-order-detail .views-field-field-cropped-photo img {
  width: auto;
  height: auto;
  max-width: 220px;
  max-height: 220px;
}

/* ---------------------------------------------------------------------------
 * Money columns
 *
 * Right-aligned so the figures line up with each other and with the
 * Subtotal / Shipping / Total block, which the order total summary renders
 * right-aligned. Left-aligned prices left the two visually unrelated and went
 * ragged once rows carried different magnitudes ($8.01 beside $400.00).
 * ------------------------------------------------------------------------ */
.view-commerce-cart-form .views-field-unit-price__number,
.view-commerce-cart-form .views-field-total-price__number,
.view-commerce-order-item-table .views-field-unit-price__number,
.view-commerce-order-item-table .views-field-total-price__number,
.tl-order-detail .views-field-unit-price__number,
.tl-order-detail .views-field-total-price__number {
  text-align: right;
}

/* .view-commerce-order-item-table is what extends this to the ADMIN and
   customer order pages, which render the same view without the checkout
   pane's .tl-order-detail wrapper. */
.view-commerce-order-item-table .views-field-quantity,
.tl-order-detail .views-field-quantity {
  text-align: center;
}

.tl-order-detail table {
  width: 100%;
  margin-bottom: 0.5rem;
}

.tl-order-detail .order-total-line {
  text-align: right;
}

/* ---------------------------------------------------------------------------
 * Checkout: the cart's two sections
 *
 * The wrapper divs come from this module's commerce-checkout-form.html.twig.
 * Same shape as the cart — an order panel with a summary panel beside it that
 * follows the customer down the page — deliberately NOT the same width: what
 * each panel holds is different, so the two pages share the pattern and each
 * states its own numbers (see Content width above).
 *
 * Shipping and payment are stacked inside the order panel rather than sitting
 * side by side. Side by side inside a panel this wide gave each about 395px,
 * less than the 584px the old two-step checkout gave them; stacked they get the
 * panel's whole width.
 * ------------------------------------------------------------------------ */
/**
 * The theme's desktop header is FIXED and 100px tall — dxpr-theme-header--top
 * sets height:100px on the menu, the branding and every nav item, and gives the
 * body a matching 100px padding-top. Anything sticky must therefore stop below
 * 100px, not at the top of the viewport, or it slides underneath the navigation
 * and cannot be read.
 *
 * Kept as a variable because three things need it and they must not drift: the
 * summary panel's sticky offset, and the same offset again for each admin
 * toolbar height.
 */
.tl-checkout {
  --tl-header: 100px;
  --tl-gap: 1rem;
  display: flex;
  align-items: flex-start;
  gap: 2rem;
  /* Room between the navigation and the first panel. Without it the panels
     start flush against the header. */
  padding-top: 1.5rem;
}

/* The admin toolbar sits ABOVE the header and pushes it down, so an admin
   looking at checkout needs the offset the theme itself uses: 39px of toolbar,
   or 80px with a tray open, on top of the header. Customers see neither. */
body.toolbar-fixed .tl-checkout {
  --tl-header: 139px;
}

body.toolbar-fixed.toolbar-tray-open.toolbar-horizontal .tl-checkout {
  --tl-header: 180px;
}

/* Both panels framed the same way, so they read as two panels rather than a
   form with something floating beside it. Matches the cart's .tl-cart-main /
   .tl-cart-side exactly. */
.tl-checkout-main,
.tl-checkout-side {
  border: 1px solid #9e9e9e;
  border-radius: 8px;
  padding: 1rem 1.25rem;
  background: #fff;
}

/* min-width: 0 stops a wide child — Stripe's iframe, a long address line —
   forcing the panel past its share of the row. */
.tl-checkout-main {
  flex: 1 1 auto;
  min-width: 0;
}

/* Narrower than the cart's 400px: that width was set by the cart's longest
   button label ("Create Another Keepsake Gift"), and this page's two buttons
   are shorter. The difference goes to the forms. */
.tl-checkout-side {
  flex: 0 0 320px;
  position: sticky;
  /* Below the fixed header, not at the top of the window — see .tl-checkout. */
  top: calc(var(--tl-header, 100px) + var(--tl-gap, 1rem));
}

/* Divides the order panel into its sections. Same grey as the rule that closes
   a gift, so the panel reads as one ruled sheet. */
.tl-checkout-divide {
  border: 0;
  border-top: 1px solid #9e9e9e;
  margin: 1.5rem 0;
}

/* Subtotal / Shipping / Total. The rule underneath separates the money from the
   button that acts on it — the same rule the cart draws under its subtotal. */
.tl-checkout-side .tl-checkout-totals {
  padding-bottom: 0.75rem;
  margin-bottom: 1rem;
  border-bottom: 1px solid #9e9e9e;
}

/* Label left, amount right, so the figures line up on one edge. Tabular digits
   so they line up on the decimal point rather than drifting. */
.tl-checkout-totals .order-total-line {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: 0.15rem 0;
}

.tl-checkout-totals .tl-total-amount {
  font-variant-numeric: tabular-nums;
}

/* The one number the customer is actually agreeing to. */
.tl-checkout-totals .tl-total-grand {
  border-top: 1px solid #ddd;
  margin-top: 0.4rem;
  padding-top: 0.5rem;
  font-size: 1.15em;
  font-weight: 700;
}

/* Stacked in the panel, one action per line, full width — the same treatment
   the cart's buttons get. Stated at this weight because this theme mixes two
   Bootstrap stylesheets and an <a> otherwise loses to a.button on
   specificity. */
.tl-checkout-side-actions .form-actions {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin: 0;
}

.tl-checkout-side-actions .form-actions input,
.tl-checkout-side-actions .form-actions button,
.tl-checkout-side-actions .form-actions a.button,
.tl-checkout-side-actions .form-actions a.button.btn,
.tl-checkout-side-actions .form-actions a.button.btn-primary {
  display: block;
  width: 100%;
  box-sizing: border-box;
  margin: 0;
  padding: 10px 16px;
  text-align: center;
}

/* ---------------------------------------------------------------------------
 * "This shipping address is correct"
 *
 * The one control standing between the customer and a parcel going to an
 * address the carrier could not find, so it has to be seen. The theme's default
 * checkbox border is too faint to read against white, and a black label reads as
 * ordinary prose rather than as something to act on.
 * ------------------------------------------------------------------------ */
.tl-address-confirm-item {
  margin: 0.75rem 0 1rem;
}

.tl-address-confirm-item label {
  color: #1a5fa8;
  font-weight: 600;
  cursor: pointer;
}

.tl-address-confirm-item input[type="checkbox"],
input.tl-address-confirm[type="checkbox"] {
  border: 2px solid #1a5fa8;
  /* The theme hands checkboxes to the browser's own control, which ignores a
     border unless the appearance is reset first. */
  appearance: none;
  -webkit-appearance: none;
  width: 18px;
  height: 18px;
  border-radius: 3px;
  background: #fff;
  vertical-align: -3px;
  margin-right: 0.4rem;
  cursor: pointer;
}

/* Drawn rather than relying on the native tick, which the reset above removes. */
input.tl-address-confirm[type="checkbox"]:checked {
  background: #1a5fa8;
  /* A tick, as an inline SVG so it needs no image file. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23ffffff' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' d='M3 8.5l3.5 3.5L13 5'/%3E%3C/svg%3E");
  background-size: 14px 14px;
  background-repeat: no-repeat;
  background-position: center;
}

input.tl-address-confirm[type="checkbox"]:focus-visible {
  outline: 2px solid #1a5fa8;
  outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
 * Pay button, not ready
 *
 * The same signal /create-photo and /create-keepsake already use when a button
 * is pressed before its requirements are met: grey means not ready, and it stays
 * clickable so that pressing it can explain why. Values match .tl-not-ready in
 * css/order.css.
 *
 * Stated at this weight because the theme mixes two Bootstrap stylesheets and a
 * plain class otherwise loses to them. Deliberately NOT shared with order.css:
 * that file styles the create-photo page's green buttons and is not loaded here,
 * and reaching across would tie two pages' palettes together.
 * ------------------------------------------------------------------------ */
.tl-checkout-side-actions .form-actions input.tl-not-ready,
.tl-checkout-side-actions .form-actions button.tl-not-ready,
input.tl-not-ready[type="submit"] {
  background: #d8d8d8;
  border-color: #d8d8d8;
  color: #777;
  /* Clickable on purpose - a disabled button cannot tell you what is wrong. */
  cursor: pointer;
}

/* Stripe's Payment Element is deliberately configured with the "night" theme,
   so it arrives dark. Nothing here recolours it — that is a setting on the
   payment gateway, not something to fight in CSS. All this does is give it the
   same breathing room as the fields above it. */
.tl-checkout-payment .checkout-pane-stripe-review {
  margin: 1rem 0;
}

@media (max-width: 900px) {
  /* The panel stops being a column and sits under the form. */
  .tl-checkout {
    display: block;
  }

  .tl-checkout-side {
    position: static;
    margin-top: 1.5rem;
  }
}

/* ---------------------------------------------------------------------------
 * Section headings
 *
 * "Shipping information" and "Payment information" are the panes' own
 * <legend>s and render at 16px/400, while the "Shipping method" / "Payment
 * method" legends nested inside them render at 20px/700 — so the subheading
 * shouted louder than the heading above it. Matched to the inner values,
 * which were read off the live page rather than guessed.
 *
 * Matching on .checkout-pane rather than a bare descendant selector keeps this
 * off the nested legends (billing address, "Shipping method" itself). A
 * direct-child selector is NOT enough: the shipping pane is wrapped in an
 * unclassed div — Drupal's AJAX replace container, present because the pane has
 * auto_recalculate enabled — so it is not a direct child of the panel. That
 * once looked like it worked because payment happens to be a direct child.
 * ------------------------------------------------------------------------ */
.tl-checkout-main fieldset.checkout-pane > legend {
  font-size: 20px;
  font-weight: 700;
}

/* The contact pane closes the payment section and its heading is suppressed —
   the value is a bare email address, and the field already carries its own
   label. See commerce-checkout-form.html.twig. */
.tl-contact-email legend {
  display: none;
}

/* ---------------------------------------------------------------------------
 * "Your gifts (Edit Cart)" heading
 *
 * Matched to the pane legends on the same page (20px/700, set above) so every
 * section of the order panel opens the same way.
 * ------------------------------------------------------------------------ */
.tl-gifts-heading {
  font-size: 20px;
  font-weight: 700;
  margin: 0 0 0.5rem;
}

/* The Edit link is deliberately lighter than the heading it sits in: it is a
   secondary escape hatch, not the action we want the customer to take. */
.tl-gifts-edit {
  font-size: 0.9375rem;
  font-weight: 400;
  text-decoration: underline;
}

/* The coupon code box only ever holds a short code, so it does not need the
   panel's full width — half reads as the minor, optional field it is, and
   stops it competing with the payment form above it. */
.checkout-pane-coupon-redemption input[type="text"] {
  max-width: 50%;
}

/* Customer Notes is optional and short, so it does not earn the panel's whole
   width either. Half keeps the foot of the panel from ending in one very wide
   empty box. */
.checkout-pane-customer-comments {
  max-width: 50%;
}

/* Below this the panel is too narrow to give anything away. */
@media (max-width: 767px) {
  .checkout-pane-customer-comments,
  .checkout-pane-coupon-redemption input[type="text"] {
    max-width: none;
  }
}

/* ---------------------------------------------------------------------------
 * Small screens
 * ------------------------------------------------------------------------ */
/* The photo shrinks on a phone but keeps a size of its own. It must NOT be
   left to `width: auto` + `max-width: 100%`: with five or six columns sharing
   a ~390px screen the browser hands the photo column about 24px, and the
   image then renders at literally 0x0 — the customer's photo vanishes from
   the page it exists to confirm. */
@media (max-width: 480px) {
  .view-commerce-cart-form .views-field-field-cropped-photo,
  .tl-order-detail .views-field-field-cropped-photo {
    width: 100px;
  }

  .view-commerce-cart-form .views-field-field-cropped-photo img,
  .tl-order-detail .views-field-field-cropped-photo img {
    max-width: 90px;
    max-height: 90px;
  }
}

/* ---------------------------------------------------------------------------
 * The Gift cell
 *
 * The gift's own name leads, with the variation it was made from underneath as
 * supporting detail. Bold matches the keepsake name in the summary column of
 * the create-keepsake page, so a gift is described the same way while it is
 * being built and after it reaches the cart.
 *
 * These deliberately live here, not in order-item-quality-flag.css: that
 * library is attached only when a print-quality warning renders, so a keepsake
 * line — which has no crop data — would never load them.
 * ------------------------------------------------------------------------ */

/* Bold covers the whole line; the italic is only on the customer's own name
   for the gift, so a suffix like "Label Reorder" stays upright. */
.tl-gift-title {
  font-weight: 700;
}

.tl-gift-name {
  font-style: italic;
}

.tl-gift-variant {
  font-size: 0.85em;
  opacity: 0.75;
  margin-top: 2px;
}
