/* ===========================================================================
   Total Machinist — WooCommerce adjustments
   Loaded ONLY on WooCommerce pages. See tm_enqueue_assets() in functions.php.

   ⚠️ WHY THIS FILE EXISTS AND site.css WAS NOT EDITED.

   site.css is copied byte-for-byte from the audited static build — 44 axe runs
   across 22 pages, zero violations. Editing it to accommodate WooCommerce
   would put store concerns into the file that carries that evidence, and the
   static build has no store pages to test the change against.

   Everything here fixes a collision between WooCommerce's own markup and a
   design decision already made and measured in site.css.
   =========================================================================== */


/* ---------------------------------------------------------------------------
   1. Clearance for the fixed "Contact us" tab.

   THE BUG, observed on the checkout 13 August 2026: the tab sat on top of the
   Last name field and the order total.

   THE CAUSE: site.css already solves this, and WooCommerce simply does not use
   the class that carries the fix. The original rule is:

       @media (min-width: 34.001rem) and (max-width: 72rem) {
         .container { padding-right: calc(var(--space-5) + 2.75rem); }
       }

   with this reasoning, quoted from site.css so it is not lost here:

       "Measured across 360–1400px, content never actually sits under the tab —
        but between roughly 620 and 1150px the gap closes to zero. A focus ring
        extends 5px past its control (3px ring + 2px offset), so at zero gap a
        focused field would have its indicator hidden behind the tab. This keeps
        real space there. Below 34rem the tab moves to the bottom of the screen,
        so no reserve needed."

   ⚠️ The breakpoints and the 2.75rem are COPIED, not re-derived. If the tab's
   size ever changes, change it in site.css and mirror it here — the two must
   agree or the checkout silently loses its clearance again.

   This matters more on checkout than anywhere else on the site: it is the one
   page where a hidden focus ring can stop someone completing a purchase.
   [WCAG 2.4.7, 1.4.11]
   --------------------------------------------------------------------------- */
@media (min-width: 34.001rem) and (max-width: 72rem) {
  .wp-block-woocommerce-checkout,
  .wp-block-woocommerce-cart,
  .woocommerce-order-received .entry-content,
  .woocommerce > .woocommerce-notices-wrapper,
  .woocommerce-page .woocommerce {
    padding-right: calc(var(--space-5) + 2.75rem);
  }
}

/* Above 72rem the tab has clear air beside a centred container, exactly as on
   the rest of the site — so no rule is needed here, deliberately. */


/* ---------------------------------------------------------------------------
   2. Hide the empty Express Checkout block.

   Express checkout is disabled in the Stripe settings (BUILD_SPEC §11: it
   would load payment-provider JavaScript on product and cart pages, which
   today make no external requests at all). WooCommerce still renders the
   heading and its "Or continue below" divider, leaving an empty framed box at
   the top of the checkout.

   ⚠️ If express checkout is ever deliberately enabled, DELETE THIS RULE or the
   buttons will be invisible and the decision will look broken rather than
   reversed.
   --------------------------------------------------------------------------- */
.wp-block-woocommerce-checkout .wc-block-components-express-payment,
.wp-block-woocommerce-checkout .wc-block-components-express-payment-continue-rule {
  display: none;
}


/* ---------------------------------------------------------------------------
   3. The content wrapper.

   `.tm-woo` is emitted by inc/woocommerce.php in place of WooCommerce's own
   `#primary > main.site-main`, which was opening a SECOND <main id="main">
   inside the one header.php already opens. It also carried no width limit, so
   product pages ran edge to edge.

   `.container` and `.stack` come from site.css and are used unchanged — the
   point is that store pages sit on the same measure and rhythm as the other
   22, not on a second layout system.
   --------------------------------------------------------------------------- */
.tm-woo > :where(h1, h2) {
  margin-block-start: 0;
}

/* /shop/ brings its own audited containers, so the wrapper there is bare. */
.tm-woo--bare {
  display: contents;
}


/* ---------------------------------------------------------------------------
   4. The single product page.

   WooCommerce floats the gallery and the summary at 48% each. With no image
   the float still reserves its column, which is what left "Related products"
   rendering one letter wide beside the title.
   --------------------------------------------------------------------------- */
.single-product .product {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-7);
  align-items: start;
}

/* ⚠️ Grid, so the floats must go — leaving them makes the two systems fight
   and the result depends on source order. */
.single-product .woocommerce-product-gallery,
.single-product .summary.entry-summary {
  float: none;
  width: auto;
  margin: 0;
}

/* No photograph: one column, and the summary is held to a readable measure
   rather than stretching the price and the facts across the full 1180px. */
/* ⚠️ Both classes are on <body>, so they are chained, not nested. Written as a
   descendant pair the rule silently never matches. */
.single-product.tm-product-no-image .product {
  grid-template-columns: minmax(0, 1fr);
}

.tm-product-no-image .summary.entry-summary {
  max-width: var(--measure);
}

/* Anything WooCommerce appends below the two columns — description tabs,
   related products where they are still shown — spans the full width. */
.single-product .product > .woocommerce-tabs,
.single-product .product > .related,
.single-product .product > .up-sells,
.single-product .product > .woocommerce-product-details__short-description {
  grid-column: 1 / -1;
}

@media (max-width: 48rem) {
  .single-product .product {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-6);
  }
}

.single-product .product_title {
  margin-block: 0 var(--space-3);
}

.woocommerce div.product p.price,
.woocommerce div.product span.price {
  font-size: 1.5rem;
  font-weight: 700;
}


/* ---------------------------------------------------------------------------
   4a. Two colours WooCommerce hard-codes, both measured failures.

   Found by running axe against the store pages for the first time on
   15 August 2026 (_axe/run-axe-store.mjs) and confirmed with a direct
   computed-style measurement, because axe was wrong about a third one.

   ⚠️ THE COMMON CAUSE: both are literal hex values in WooCommerce's own
   stylesheet. They are identical in light and dark because they never look at
   the theme at all — #767676 sits on #f4f6f9 and on #0b0f16 alike. Pointing
   them at the site's tokens fixes both themes at once and is not a redesign:
   it is the palette the rest of the site already uses.

     breadcrumb   #767676 on #f4f6f9 = 4.20:1   needs 4.5  [WCAG 1.4.3]
                  #767676 on #0b0f16 = 4.23:1   needs 4.5
     loop price   #958e09 on #f4f6f9 = 3.15:1   needs 4.5 at 15.4px

   After, measured on the same grounds:
     breadcrumb   --ink-soft  = 8.76:1 light,  passes dark
     links        --navy      = 14.1:1 light
     loop price   --brass     = 5.26:1 light,  9.0:1 dark

   The single-product price escaped the report only because it is 24px bold,
   where the threshold drops to 3:1 — it was passing at 3.15:1 with no margin.
   This fixes that too.
   --------------------------------------------------------------------------- */
.woocommerce .woocommerce-breadcrumb {
  color: var(--ink-soft);
}

.woocommerce .woocommerce-breadcrumb a {
  color: var(--navy);
}

.woocommerce .price,
.woocommerce .price bdi,
.woocommerce div.product p.price,
.woocommerce div.product span.price,
.woocommerce ul.products li.product .price {
  color: var(--brass);
}

.single-product form.cart {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-4);
  margin-block: var(--space-6);
}

/* ⚠️ The WIDTH is the part that matters, not the height. WooCommerce's default
   box is sized for the digits alone, and a number input also has to hold the
   browser's own up/down spinner — so at the default the "1" sat jammed against
   the arrows and was partly hidden behind them.
   [WCAG 3.3.2] A field whose own value you cannot read is not usable, and the
   quantity is what the buyer is charged for. 5rem holds two digits and the
   spinner with air around both; `text-align: center` keeps it readable when it
   goes to double figures. */
.single-product form.cart .quantity input {
  box-sizing: border-box;
  width: 5rem;
  min-height: 2.75rem;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--paper);
  color: var(--ink);
  font-size: var(--text-base);
  text-align: center;
}

/* ⚠️ 2.75rem is the site's minimum control height, not a number chosen here.
   [WCAG 2.5.8] Target size. Match site.css if that ever changes. */


/* ---------------------------------------------------------------------------
   4b. Buttons.

   WooCommerce ships its own purple. The site has one button system in site.css
   and a store button that does not look like every other button on the site
   reads as a different site — at the exact moment the visitor is deciding
   whether to trust it with a card.

   ⚠️ The values are COPIED from site.css .btn / .btn--primary, not re-chosen.
   If the palette moves there, mirror it here. And do NOT add a colour
   transition: site.css documents that Chromium keeps the stale colour through
   a light/dark switch, which measured 1.15:1 against a 4.5:1 requirement.
   --------------------------------------------------------------------------- */
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit,
.woocommerce a.button.alt,
.woocommerce button.button.alt,
.woocommerce input.button.alt {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-3) var(--space-5);
  border: 2px solid var(--navy);
  border-radius: var(--radius);
  background: var(--navy);
  color: var(--on-navy);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: bold;
  line-height: 1.2;
  text-decoration: none;
}

.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce a.button.alt:hover,
.woocommerce button.button.alt:hover,
.woocommerce input.button.alt:hover {
  background: var(--navy-hover);
  border-color: var(--navy-hover);
  color: var(--on-navy);
}

/* ⚠️ The BLOCK buttons are a separate set of class names and were missed by
   the rules above. Found on the empty-cart page, which renders a "New in
   store" grid — dark grey pills with fully rounded corners, on a site whose
   every other button is a navy rectangle.
   Easy to miss because the empty cart is a state nobody tests: you have to
   arrive at the cart with nothing in it. */
.wc-block-components-button:not(.is-link),
.wc-block-components-product-button__button,
.wp-block-woocommerce-cart .wc-block-cart__submit-button,
.wc-block-components-checkout-place-order-button {
  min-height: 44px;
  padding: var(--space-3) var(--space-5);
  border: 2px solid var(--navy);
  border-radius: var(--radius);
  background: var(--navy);
  color: var(--on-navy);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: bold;
  line-height: 1.2;
}

.wc-block-components-button:not(.is-link):hover,
.wc-block-components-product-button__button:hover,
.wp-block-woocommerce-cart .wc-block-cart__submit-button:hover,
.wc-block-components-checkout-place-order-button:hover {
  background: var(--navy-hover);
  border-color: var(--navy-hover);
  color: var(--on-navy);
}


/* ---------------------------------------------------------------------------
   4c. The shop sidebar.

   WooCommerce calls get_sidebar( 'shop' ) from its own templates. This theme
   registers no sidebar, so WordPress fell back to the default widget set and
   every product page ended with a search box and a bulleted list of all 22
   pages — below the Add to cart button, styled as raw browser defaults.

   Removed in inc/woocommerce.php rather than hidden here, so the markup is
   never emitted. This rule is the belt to that braces, for any WooCommerce
   template that calls the sidebar through a path the action does not cover.
   --------------------------------------------------------------------------- */
.woocommerce-page .widget-area,
.single-product #secondary,
.single-product .widget-area {
  display: none;
}


/* ---------------------------------------------------------------------------
   4d. The placeholder image.

   No product has a photograph yet, so WooCommerce renders its grey
   "image missing" icon on the shop grid, the cart line and the industry
   product pages. It reads as a broken image rather than as a product without
   a picture.

   ⚠️ Hidden, not removed, and this is the difference: class products will
   never have a photograph (inc/woocommerce.php drops their gallery outright),
   but INDUSTRY products should have one — Chris has not supplied them yet
   (TODO 2.4). The moment a real image is set on a product it appears, with
   nothing to undo here.
   --------------------------------------------------------------------------- */
/* ⚠️ TWO selectors, because the placeholder arrives two different ways. The
   classic templates give the <img> a `woocommerce-placeholder` CLASS; the
   block cart and checkout give it no class at all and only the FILENAME
   identifies it. Matching the class alone left the grey square sitting in the
   order summary — the one place the buyer is checking what they are paying
   for. */
img.woocommerce-placeholder,
img[src*="woocommerce-placeholder"] {
  display: none;
}

/* The order summary's image box also holds the quantity badge, so the box
   keeps its footprint — otherwise the badge collapses onto the product name. */
.wc-block-components-order-summary-item__image {
  min-width: 2.5rem;
}


/* ---------------------------------------------------------------------------
   4f. "Continue shopping" / "Return to cart".

   Emitted by inc/woocommerce.php. Set as ordinary links rather than buttons:
   they are the way back, not the thing the page is for, and a second button
   beside "Place order" competes with the action the visitor came to take.
   --------------------------------------------------------------------------- */
.tm-continue-shopping {
  margin-block-start: var(--space-6);
}

.tm-continue-shopping a {
  color: var(--navy);
}


/* ---------------------------------------------------------------------------
   4e. ⚠️ A CLASS-NAME COLLISION, not a styling choice.

   THE SYMPTOM, 15 August 2026: in the checkout order summary the prices
   rendered at 33px bold — bigger than the product name, overlapping it, and
   with the line total and the unit price both shouting at the same size.

   THE CAUSE: site.css §16 sets

       .price { font-size: var(--text-2xl); font-weight: bold; }

   deliberately, and it must stay. On the Industry Store cards the price is
   meant to be the largest thing in its block — it has to be unmissable before
   any commitment. That is a measured decision, not decoration.

   WooCommerce Blocks happens to put the same bare class name `price` on its
   own price elements, so every price in the cart and checkout inherited a
   treatment designed for a product card. The parent elements were 13px and
   the price inside them was 33px.

   ⚠️ Do NOT fix this by changing site.css. That file carries the accessibility
   audit, and the Industry cards need the rule exactly as it is. The collision
   belongs to the store, so the correction lives here.

   Matching on `[class*="wc-block"]` scopes this to block markup only — the
   classic product loop is untouched, where WooCommerce's own rule already
   sizes the price correctly.
   --------------------------------------------------------------------------- */
[class*="wc-block"].price,
[class*="wc-block"] .price {
  font-size: inherit;
  font-weight: inherit;
}

/* ⚠️ No rule for the grand total, deliberately. WooCommerce already sets it at
   20px against the 13px line items, so it is clearly the largest number on the
   panel — which is the property that matters. An earlier version added a
   font-weight here; it was measured afterwards and lost to a more specific
   WooCommerce rule, so it was doing nothing and has been removed rather than
   left in looking load-bearing. */


/* ---------------------------------------------------------------------------
   5. The class facts.

   Emitted by the i2L Class Codes plugin. BUILD_SPEC §8.4: instructor is the
   only guard against an instructor handing out the wrong code, so it is set as
   a labelled pair a student can check at a glance, not as prose.
   --------------------------------------------------------------------------- */
.i2l-class-facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-2) var(--space-5);
  margin-block: var(--space-5);
  padding: var(--space-5);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--navy-tint);
}

.i2l-class-facts dt {
  font-weight: 700;
  color: var(--ink-soft);
}

.i2l-class-facts dd {
  margin: 0;
  color: var(--ink);
}

/* The code itself is the thing a student compares against their syllabus
   character by character, so it is set in the monospace face. */
.i2l-class-facts dd:first-of-type {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

@media (max-width: 34rem) {
  .i2l-class-facts {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }
  .i2l-class-facts dd {
    margin-block-end: var(--space-4);
  }
}
