/*
 * The WooCommerce pages the design boards do not draw.
 *
 * canvas-c covers the shop grid, the cart panel beside it and the checkout.
 * WooCommerce also ships a stand-alone cart page, an account area with a login
 * form, an order-received page and a set of notices, and every one of them is
 * reachable: the product cards fall back to posting to /cart/ without
 * JavaScript, WooCommerce's own "View cart" notice links there, and the account
 * pages are where a customer looks up an order. Measured before this file
 * existed, /cart/ and /my-account/ rendered as stock WooCommerce: a blue-bordered
 * notice, a grey Log in button, white inputs, red asterisks. The brief says not
 * to leave the default WooCommerce design.
 *
 * Nothing here invents a layout. It maps WooCommerce's own components onto the
 * tokens the rest of the site already uses, so these pages look like the site
 * without claiming to be a drawing anybody approved.
 *
 * ON THE SELECTORS, the same warning as checkout.css: WooCommerce writes rules
 * like `.woocommerce table.shop_table td` and `.woocommerce #respond input#submit,
 * .woocommerce a.button`. A plain `.shop_table td` loses and does nothing. Every
 * rule below that competes borrows WooCommerce's own scope, and this sheet loads
 * after theirs, so a tie is enough.
 *
 * @package COF
 */

/* ------------------------------------------------------------- The frame --- */

/*
 * page.php wraps the_content() in .cof-prose, which is the measure and rhythm of
 * a legal page. A cart is not prose: it is a table that wants the full column.
 */
body.woocommerce-cart .cof-prose,
body.woocommerce-account .cof-prose,
body.woocommerce-order-received .cof-prose {
  max-width: none;
  line-height: normal;
}

/* -------------------------------------------------------------- Notices --- */

/*
 * WooCommerce's messages are the only place the shop speaks to a visitor about
 * something going wrong, so they are brought into the palette rather than left
 * in WooCommerce's blue and green. Not scoped to .woocommerce-notices-wrapper:
 * the cart page prints its empty-cart message as a bare .woocommerce-info inside
 * .woocommerce, which is why that one stayed blue when only the wrapper was
 * styled.
 */
.woocommerce .woocommerce-message,
.woocommerce .woocommerce-info,
.woocommerce .woocommerce-error,
.woocommerce-notices-wrapper .woocommerce-message,
.woocommerce-notices-wrapper .woocommerce-info,
.woocommerce-notices-wrapper .woocommerce-error {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 20px;
  margin: 0 0 28px;
  padding: 16px 20px;
  background: var(--cof-card);
  border: 0;
  border-left: 3px solid var(--cof-control);
  border-radius: var(--cof-r-input);
  color: var(--cof-ink);
  font-size: 15px;
  line-height: 1.6;
  list-style: none;
}
.woocommerce .woocommerce-error,
.woocommerce-notices-wrapper .woocommerce-error { border-left-color: #8B2F1F; color: #7A2818; }

/* WooCommerce's own icon is a ::before glyph from its font stack. */
.woocommerce .woocommerce-message::before,
.woocommerce .woocommerce-info::before,
.woocommerce .woocommerce-error::before,
.woocommerce-notices-wrapper .woocommerce-message::before,
.woocommerce-notices-wrapper .woocommerce-info::before,
.woocommerce-notices-wrapper .woocommerce-error::before { content: none; }

/* An error notice with several problems in it is a list, and stays one. */
.woocommerce .woocommerce-error { flex-direction: column; align-items: flex-start; }
.woocommerce .woocommerce-error li { margin: 0; }

/* -------------------------------------------------------------- Buttons --- */

/*
 * (0,2,1), matching `.woocommerce a.button` and `.woocommerce button.button`.
 * The theme's own .cof-btn is not reused by adding the class in PHP, because
 * these buttons are printed by WooCommerce templates this theme does not
 * override; the styling has to reach them where they are.
 */
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce a.button.alt,
.woocommerce button.button.alt,
.woocommerce input.button.alt,
.woocommerce #respond input#submit,
.woocommerce .woocommerce-Button,
.woocommerce-notices-wrapper .button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  min-height: 52px;
  padding: 15px 30px;
  background: var(--cof-espresso);
  border: 1px solid var(--cof-espresso);
  border-radius: 0;
  color: var(--cof-on-dark);
  font-family: inherit;
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0.12em;
  line-height: 1.2;
  text-transform: uppercase;
  text-decoration: none;
  text-shadow: none;
  transition: background 0.18s var(--cof-ease), color 0.18s var(--cof-ease);
}
.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,
.woocommerce #respond input#submit:hover,
.woocommerce .woocommerce-Button:hover,
.woocommerce-notices-wrapper .button:hover {
  background: var(--cof-ink);
  border-color: var(--cof-ink);
  color: var(--cof-on-dark);
}

/*
 * A disabled Update cart button. WooCommerce ships `opacity: .25`, which takes a
 * 12:1 label down to about 1.6:1 and makes the reason for the state unreadable.
 */
.woocommerce a.button.disabled,
.woocommerce button.button:disabled,
.woocommerce button.button:disabled[disabled],
.woocommerce input.button:disabled {
  opacity: 1;
  background: var(--cof-deep-sand);
  border-color: var(--cof-control);
  color: var(--cof-body);
  cursor: not-allowed;
}

/* The secondary weight: coupon Apply, address Update, shipping Calculate. */
.woocommerce .coupon button.button,
.woocommerce .shipping-calculator-form button.button {
  background: transparent;
  border-color: var(--cof-control);
  color: var(--cof-ink);
}
.woocommerce .coupon button.button:hover,
.woocommerce .shipping-calculator-form button.button:hover {
  background: var(--cof-espresso);
  border-color: var(--cof-espresso);
  color: var(--cof-on-dark);
}

/* --------------------------------------------------------------- Fields --- */

/*
 * EVERY RULE FROM HERE TO THE CART SECTION IS SCOPED AWAY FROM THE CHECKOUT.
 *
 * This file is for the pages nobody drew. The checkout was drawn, and
 * checkout.css already says what its six fields, its shipping options and its
 * summary table look like. Without the `body:not(.woocommerce-checkout)` prefix
 * these generic rules reached it anyway and quietly changed three things,
 * measured by loading the page twice with this sheet enabled and disabled: the
 * shipping option's label dropped from 15px to 12px because `.woocommerce label`
 * is (0,1,1) and `.cof-option__label` is only (0,1,0); the summary table gained
 * a 32px bottom margin from `.woocommerce table.shop_table`, which is (0,2,1)
 * against checkout.css's (0,1,0); and the summary card grew 25px taller as a
 * result. A stylesheet meant to fill a gap had started editing a design the
 * client had already approved.
 */

/*
 * (0,3,2), matching `.woocommerce form .form-row input.input-text`. checkout.css
 * says the same thing for the checkout's own six fields; this covers the account
 * forms, the coupon box, the quantity box and the shipping calculator, which are
 * all outside that scope.
 */
body:not(.woocommerce-checkout) .woocommerce form .form-row input.input-text,
body:not(.woocommerce-checkout) .woocommerce form .form-row textarea,
body:not(.woocommerce-checkout) .woocommerce form .form-row select,
body:not(.woocommerce-checkout) .woocommerce input.input-text,
body:not(.woocommerce-checkout) .woocommerce input[type="text"],
body:not(.woocommerce-checkout) .woocommerce input[type="email"],
body:not(.woocommerce-checkout) .woocommerce input[type="tel"],
body:not(.woocommerce-checkout) .woocommerce input[type="password"],
body:not(.woocommerce-checkout) .woocommerce input[type="number"],
body:not(.woocommerce-checkout) .woocommerce select,
body:not(.woocommerce-checkout) .woocommerce textarea {
  box-sizing: border-box;
  min-height: 50px;
  padding: 13px 18px;
  background: var(--cof-card);
  border: 1px solid var(--cof-control);
  border-radius: var(--cof-r-input);
  color: var(--cof-ink);
  font-family: inherit;
  font-size: 15px;
  line-height: 1.4;
}
body:not(.woocommerce-checkout) .woocommerce textarea { min-height: 116px; resize: vertical; }
body:not(.woocommerce-checkout) .woocommerce ::placeholder { color: var(--cof-muted); opacity: 1; }

body:not(.woocommerce-checkout) .woocommerce form .form-row label,
body:not(.woocommerce-checkout) .woocommerce label {
  display: block;
  margin-bottom: 7px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--cof-body);
}
/*
 * WooCommerce prints the required marker as `<abbr class="required" title="required">*`
 * in red, with a dotted underline from the browser's own abbr styling.
 */
/* (0,3,0), matching `.woocommerce form .form-row .required`, which is where the
   red comes from. A plain `.woocommerce .required` is (0,2,0) and loses. */
body:not(.woocommerce-checkout) .woocommerce form .form-row .required,
body:not(.woocommerce-checkout) .woocommerce form .form-row abbr.required,
body:not(.woocommerce-checkout) .woocommerce .required,
body:not(.woocommerce-checkout) .woocommerce abbr.required {
  color: var(--cof-flag);
  font-weight: 500;
  border: 0;
  text-decoration: none;
}
body:not(.woocommerce-checkout) .woocommerce .optional { color: var(--cof-muted); }

/* A checkbox in a WooCommerce form: Remember me, and the account terms box. */
body:not(.woocommerce-checkout) .woocommerce input[type="checkbox"],
body:not(.woocommerce-checkout) .woocommerce input[type="radio"] {
  width: 20px;
  height: 20px;
  min-height: 0;
  margin: 0 8px 0 0;
  padding: 0;
  accent-color: var(--cof-espresso);
  vertical-align: middle;
}
body:not(.woocommerce-checkout) .woocommerce label.woocommerce-form__label-for-checkbox {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin: 0;
  font-size: 14px;
  letter-spacing: normal;
  text-transform: none;
  cursor: pointer;
}
body:not(.woocommerce-checkout) .woocommerce label.woocommerce-form__label-for-checkbox span { margin-left: 4px; }

/* --------------------------------------------------------------- Tables --- */

/*
 * (0,2,1), matching `.woocommerce table.shop_table`. WooCommerce draws a 1px
 * box with a 5px radius around every table and a border on each cell; the site
 * uses hairlines between rows and nothing around them.
 */
body:not(.woocommerce-checkout) .woocommerce table.shop_table {
  width: 100%;
  margin: 0 0 32px;
  border: 0;
  border-radius: 0;
  border-collapse: collapse;
  font-size: 15px;
  color: var(--cof-ink);
}
body:not(.woocommerce-checkout) .woocommerce table.shop_table th,
body:not(.woocommerce-checkout) .woocommerce table.shop_table td {
  padding: 18px 12px;
  border: 0;
  border-bottom: 1px solid var(--cof-hairline);
  vertical-align: middle;
  line-height: 1.5;
}
body:not(.woocommerce-checkout) .woocommerce table.shop_table thead th {
  padding-bottom: 12px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--cof-body);
}
body:not(.woocommerce-checkout) .woocommerce table.shop_table tbody tr:last-child td { border-bottom: 1px solid var(--cof-hairline); }
body:not(.woocommerce-checkout) .woocommerce table.shop_table th:first-child,
body:not(.woocommerce-checkout) .woocommerce table.shop_table td:first-child { padding-left: 0; }
body:not(.woocommerce-checkout) .woocommerce table.shop_table th:last-child,
body:not(.woocommerce-checkout) .woocommerce table.shop_table td:last-child { padding-right: 0; text-align: right; }

/* ----------------------------------------------------------- Cart page --- */

.woocommerce table.shop_table.cart td.product-thumbnail img {
  width: 74px;
  max-width: none;
  height: auto;
  border-radius: var(--cof-r-thumb);
  display: block;
}
.woocommerce table.shop_table.cart td.product-thumbnail { width: 74px; }
.woocommerce table.shop_table.cart td.product-name a {
  color: var(--cof-ink);
  font-family: var(--cof-serif);
  font-size: 18px;
}
.woocommerce table.shop_table.cart td.product-name a:hover { color: var(--cof-flag); }

/*
 * The remove control. WooCommerce renders a 1em "x" glyph, which measured 24x24
 * and reads as a punctuation mark rather than a button.
 */
.woocommerce table.shop_table.cart td.product-remove { width: 44px; }
.woocommerce a.remove {
  display: flex;
  align-items: center;
  justify-content: center;
  position: static;
  width: 44px;
  height: 44px;
  margin: 0;
  border-radius: 50%;
  background: transparent;
  /* !important, to answer WooCommerce's own: `a.remove { color: var(--wc-red)
     !important }`. Nothing but an author !important outranks an author
     !important, and a bright red x on a cream page is the one colour on this
     site that belongs to no palette at all. */
  color: var(--cof-body) !important;
  font-size: 22px;
  font-weight: 400;
  line-height: 1;
  text-decoration: none;
}
.woocommerce a.remove:hover { background: var(--cof-deep-sand); color: var(--cof-ink) !important; }

/* The quantity box, which WooCommerce leaves at browser defaults. */
.woocommerce .quantity input.qty,
.woocommerce div.quantity input.qty {
  box-sizing: border-box;
  width: 76px;
  min-height: 48px;
  padding: 10px 6px 10px 12px;
  background: var(--cof-card);
  border: 1px solid var(--cof-control);
  border-radius: var(--cof-r-input);
  color: var(--cof-ink);
  font-size: 15px;
  text-align: center;
}

/* The row holding Update cart and the coupon box. */
.woocommerce table.shop_table.cart td.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 24px 0 0;
  border-bottom: 0;
}
/* A flex item shrinks below its content by default, which wrapped the two words
   of "Update cart" onto two lines inside a box narrower than the label. */
.woocommerce table.shop_table.cart td.actions button.button { flex: none; }
.woocommerce table.shop_table.cart td.actions .coupon {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  float: none;
}
.woocommerce table.shop_table.cart td.actions .coupon label { display: none; }
.woocommerce table.shop_table.cart td.actions .coupon input.input-text {
  width: 220px;
  margin: 0;
}

/* The totals block beside, or under, the cart. */
.woocommerce .cart-collaterals { width: 100%; }
.woocommerce .cart-collaterals .cart_totals {
  float: none;
  width: 100%;
  max-width: 440px;
  margin-left: auto;
  padding: 28px 30px;
  background: var(--cof-card);
  border-radius: var(--cof-r-card);
}
.woocommerce .cart_totals h2 {
  margin: 0 0 18px;
  font-family: var(--cof-sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--cof-ink);
}
.woocommerce .cart_totals table.shop_table { margin: 0; }
.woocommerce .cart_totals table.shop_table th { font-weight: 500; text-align: left; }
.woocommerce .cart_totals table.shop_table tr:last-child th,
.woocommerce .cart_totals table.shop_table tr:last-child td { border-bottom: 0; }
.woocommerce .cart_totals tr.order-total th,
.woocommerce .cart_totals tr.order-total td { font-size: 17px; }
/*
 * The "(includes EUR 7.81 MwSt.)" note. WooCommerce sets it to #767676, which is
 * 3.77:1 on the card and fails AA for 14px text, at (0,3,1):
 * `.woocommerce-cart .cart-collaterals .cart_totals table small`. Answered at
 * the same shape. The figure it carries is the tax a customer is being charged,
 * which is not a detail to render at the edge of legibility.
 */
.woocommerce-cart .cart-collaterals .cart_totals table small,
.woocommerce-checkout .cart-collaterals .cart_totals table small { color: var(--cof-muted); }

.woocommerce .cart_totals ul#shipping_method { margin: 0; padding: 0; list-style: none; text-align: right; }
.woocommerce .cart_totals ul#shipping_method li { margin: 0 0 6px; }
.woocommerce .woocommerce-shipping-destination { margin: 8px 0 0; font-size: 13px; color: var(--cof-muted); }
.woocommerce a.shipping-calculator-button {
  display: inline-block;
  min-height: 44px;
  padding-block: 12px;
  color: var(--cof-ink);
  font-size: 13px;
  text-decoration: underline;
  text-underline-offset: 3px;
}
/*
 * WooCommerce appends a truck from its own icon font, which is a piece of
 * decoration the rest of this site does not use and which duplicates the trust
 * strip's own truck.
 *
 * The selector is (0,3,0) because theirs is: `.woocommerce-cart
 * .cart-collaterals .shipping-calculator-button::after`. Written the obvious way
 * as `.woocommerce a.shipping-calculator-button::after` it is (0,2,1), three
 * classes beats two classes and an element, and the glyph stayed. It briefly
 * looked fixed because `display: none` did win, WooCommerce not having declared
 * display there, which is a coincidence rather than a rule.
 */
.woocommerce-cart .cart-collaterals .shipping-calculator-button::after,
.woocommerce-checkout .cart-collaterals .shipping-calculator-button::after { content: none; }
.woocommerce .shipping-calculator-form { margin-top: 10px; text-align: left; }
.woocommerce .shipping-calculator-form .form-row { margin: 0 0 12px; }

.woocommerce .wc-proceed-to-checkout { padding: 20px 0 0; }
.woocommerce .wc-proceed-to-checkout a.checkout-button { display: flex; width: 100%; }

/* The empty cart. */
.woocommerce .cart-empty { margin-bottom: 20px; }
.woocommerce .return-to-shop { margin: 0; }

/* ------------------------------------------------------------- Account --- */

/*
 * Two columns on a desktop, stacked on a phone. WooCommerce floats the
 * navigation at 30% and the content at 68%, which is a float layout inside a
 * grid page and collapses the moment anything is taller than expected.
 */
.woocommerce-account .woocommerce {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 44px;
  align-items: start;
}
/*
 * WooCommerce clearfixes .woocommerce with `::before { content: " "; display:
 * table }`, and a pseudo-element is a grid item like any other. It silently took
 * the 240px cell, so the navigation landed in the wide column and the content
 * wrapped onto a second row in the narrow one. checkout.css carries the same
 * note about the same clearfix breaking a flex column: it is the same bug in a
 * different layout mode, and it is invisible until something measures a box.
 */
.woocommerce-account .woocommerce::before,
.woocommerce-account .woocommerce::after { content: none; }
/* A logged-out account page is one login form and no navigation. */
.woocommerce-account.woocommerce-no-nav .woocommerce,
.woocommerce-account .woocommerce:not(:has(.woocommerce-MyAccount-navigation)) {
  display: block;
}

/*
 * The notices wrapper is WooCommerce's first child on every page, so in a
 * two-column grid it claimed the navigation's cell and pushed the content onto a
 * second row under it. It is a full-width band wherever it appears.
 */
.woocommerce-account .woocommerce > .woocommerce-notices-wrapper { grid-column: 1 / -1; }
.woocommerce-account .woocommerce > .woocommerce-notices-wrapper:empty { display: none; }

.woocommerce-account .woocommerce-MyAccount-navigation { float: none; width: auto; }
.woocommerce-account .woocommerce-MyAccount-navigation ul {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--cof-hairline);
}
.woocommerce-account .woocommerce-MyAccount-navigation li {
  margin: 0;
  border-bottom: 1px solid var(--cof-hairline);
}
.woocommerce-account .woocommerce-MyAccount-navigation li a {
  display: flex;
  align-items: center;
  min-height: 52px;
  padding: 12px 0;
  color: var(--cof-body);
  font-size: 14px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.woocommerce-account .woocommerce-MyAccount-navigation li.is-active a,
.woocommerce-account .woocommerce-MyAccount-navigation li a:hover { color: var(--cof-ink); }
.woocommerce-account .woocommerce-MyAccount-navigation li.is-active a { font-weight: 600; }

.woocommerce-account .woocommerce-MyAccount-content { float: none; width: auto; }
.woocommerce-account .woocommerce-MyAccount-content p { margin-bottom: 16px; line-height: 1.7; }

/*
 * The login and register forms. WooCommerce boxes them in a 2px grey border
 * with a 5px radius.
 */
.woocommerce .woocommerce-form-login,
.woocommerce .woocommerce-form-register,
.woocommerce .woocommerce-ResetPassword,
.woocommerce .woocommerce-EditAccountForm,
.woocommerce form.edit-account {
  max-width: 480px;
  margin: 0;
  padding: 30px;
  background: var(--cof-card);
  border: 0;
  border-radius: var(--cof-r-card);
}
.woocommerce .woocommerce-form-login .form-row,
.woocommerce .woocommerce-form-register .form-row { margin: 0 0 18px; padding: 0; }
.woocommerce .woocommerce-form-login__submit,
.woocommerce .woocommerce-form-register__submit { float: none; margin: 0; }
/*
 * Remember me and the submit button are siblings in one <p>, and WooCommerce
 * floats the button left, which put a 52px button beside a stranded checkbox and
 * in the opposite order to the markup. The float is dropped above; stacking them
 * here puts the choice above the action, which is the order they are read in.
 */
.woocommerce .woocommerce-form-login p.form-row:has(.woocommerce-form-login__submit),
.woocommerce .woocommerce-form-register p.form-row:has(.woocommerce-form-register__submit) {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 18px;
  margin-bottom: 0;
}
.woocommerce label.woocommerce-form-login__rememberme { margin: 0; }
/* The Password change block is a bare <fieldset>, so it renders with the
   browser's own groove border and a legend notched into it. */
.woocommerce fieldset {
  margin: 8px 0 18px;
  padding: 20px 0 0;
  border: 0;
  border-top: 1px solid var(--cof-hairline);
}
.woocommerce fieldset legend {
  padding: 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--cof-ink);
}
.woocommerce fieldset legend + .form-row,
.woocommerce fieldset .form-row:first-of-type { margin-top: 16px; }

/* WooCommerce's field hints are <span class="description">, unstyled. */
.woocommerce span.description,
.woocommerce em {
  display: block;
  margin-top: 6px;
  font-size: 13px;
  font-style: normal;
  line-height: 1.5;
  color: var(--cof-muted);
}

.woocommerce .woocommerce-LostPassword { margin: 16px 0 0; }
.woocommerce .woocommerce-LostPassword a {
  display: inline-block;
  min-height: 44px;
  padding-block: 12px;
  color: var(--cof-ink);
  font-size: 14px;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/*
 * The show-password eye. WooCommerce absolutely positions it inside the field
 * and gives it no size of its own, which measured 22x22.
 */
.woocommerce .woocommerce-form-login .password-input,
.woocommerce .woocommerce-form-register .password-input,
.woocommerce .password-input { display: block; position: relative; }
.woocommerce .show-password-input {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

/* The address cards on the account's Addresses tab. */
.woocommerce .woocommerce-Addresses .woocommerce-Address {
  padding: 24px 26px;
  background: var(--cof-card);
  border-radius: var(--cof-r-card);
}
/* WooCommerce floats the "Add address" link right of the heading, which on a
   card narrower than the two put together drops it into the address itself. */
.woocommerce .woocommerce-Address-title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
}
.woocommerce .woocommerce-Address-title a {
  flex: none;
  float: none;
  font-size: 13px;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.woocommerce .woocommerce-Address-title h2,
.woocommerce .woocommerce-Address-title h3 {
  margin: 0;
  font-family: var(--cof-sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}
.woocommerce .woocommerce-Address address { font-style: normal; line-height: 1.7; }

/* ---------------------------------------------------------- Order pages --- */

.woocommerce .woocommerce-order-overview,
.woocommerce ul.order_details {
  display: flex;
  flex-wrap: wrap;
  gap: 20px 40px;
  margin: 0 0 32px;
  padding: 24px 26px;
  background: var(--cof-card);
  border-radius: var(--cof-r-card);
  list-style: none;
}
.woocommerce ul.order_details li {
  margin: 0;
  padding: 0;
  border: 0;
  float: none;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cof-body);
}
.woocommerce ul.order_details li strong {
  display: block;
  margin-top: 6px;
  font-family: var(--cof-serif);
  font-size: 18px;
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  color: var(--cof-ink);
}

/* ----------------------------------------------------------- Responsive --- */

@media (max-width: 900px) {
  .woocommerce-account .woocommerce { grid-template-columns: minmax(0, 1fr); gap: 30px; }
  .woocommerce .cart-collaterals .cart_totals { max-width: none; margin-left: 0; }
}

@media (max-width: 720px) {
  /*
   * WooCommerce's own small-screen sheet turns .shop_table_responsive into a
   * stack of rows, each cell labelled from its data-title attribute. That
   * behaviour is kept and restyled rather than replaced, because it is what the
   * markup was written for.
   */
  .woocommerce table.shop_table_responsive tr {
    display: block;
    margin-bottom: 18px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--cof-hairline);
  }
  .woocommerce table.shop_table_responsive tr:last-child { border-bottom: 0; }
  .woocommerce table.shop_table_responsive td {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 8px 0;
    border-bottom: 0;
    text-align: right;
  }
  .woocommerce table.shop_table_responsive td::before {
    content: attr(data-title) ": ";
    font-size: 12px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--cof-body);
  }
  .woocommerce table.shop_table_responsive td.product-remove::before,
  .woocommerce table.shop_table_responsive td.product-thumbnail::before,
  .woocommerce table.shop_table_responsive td.actions::before { content: none; }

  /*
   * WooCommerce hides the thumbnail on a small screen, at (0,3,1). A cart line
   * is easier to recognise by its picture than by its name, and the picture is
   * the one thing a phone has room for. Matched at (0,4,1) to bring it back.
   */
  .woocommerce table.shop_table.cart td.product-thumbnail,
  .woocommerce-page table.shop_table.cart td.product-thumbnail { display: block; width: auto; }
  .woocommerce table.shop_table.cart td.product-thumbnail img { width: 96px; }
  .woocommerce table.shop_table_responsive tr.cart_item {
    display: grid;
    grid-template-columns: 96px minmax(0, 1fr);
    gap: 4px 18px;
    align-items: start;
  }
  .woocommerce table.shop_table_responsive tr.cart_item td.product-thumbnail { grid-row: 1 / span 5; }
  .woocommerce table.shop_table_responsive tr.cart_item td.product-remove { justify-content: flex-end; }
  .woocommerce table.shop_table.cart td.actions { justify-content: stretch; }
  .woocommerce table.shop_table.cart td.actions .coupon,
  .woocommerce table.shop_table.cart td.actions .coupon input.input-text,
  .woocommerce table.shop_table.cart td.actions button.button { width: 100%; }
}

/* --------------------------------------------------- Single product page --- */

/*
 * The board draws no single product page, so this is the same job as the cart and
 * the account area: WooCommerce's own components in the COF palette, no invented
 * layout.
 *
 * It starts with a bug rather than a preference. WooCommerce floats the gallery
 * left and the summary right, at 48% each, and nothing clears them. Measured on
 * this page before the fix: `div.product` was 1288x0, `.cof-container` was 1440x0,
 * the section wrapper collapsed to 176px, and the FOOTER flowed up beside the
 * floats and rendered its two-column nav grid at 10.77px per column. The page
 * looked broken from the middle down, and the cause was two lines of WooCommerce
 * CSS on a page nobody had styled.
 *
 * Replacing the floats with a grid fixes the collapse at the root: a grid
 * container has the height of its rows, so there is nothing to clear.
 *
 * Specificity: WooCommerce writes `.woocommerce div.product div.images` at
 * (0,3,2). These carry a body class as well, at (0,4,2), so they win wherever
 * this sheet happens to sit in the cascade.
 */
/*
 * The gallery column is capped rather than proportional, and the cap is set by
 * the photograph rather than by taste.
 *
 * Both product originals are 278x430 pixels. That is the whole file; WordPress
 * does not upscale, so `cof-product` (440x733) was never generated and no larger
 * version exists. Left to fill half of a 1288px container the image was displayed
 * at 638x986, a 2.3x upscale, and it showed.
 *
 * 460px holds it to roughly 1.55x, which is what the shop grid already does with
 * the same file, so the product page is no softer than the page a visitor
 * arrives from. Raising this cap needs bigger photographs first: open question 3.
 */
body.single-product div.product {
  display: grid;
  grid-template-columns: minmax(0, 460px) minmax(0, 1fr);
  gap: 24px 60px;
  align-items: start;
}
body.single-product .woocommerce div.product div.images,
body.single-product div.product div.images {
  float: none;
  width: auto;
  margin: 0;
}
body.single-product .woocommerce div.product div.summary,
body.single-product div.product div.summary {
  float: none;
  width: auto;
  max-width: 560px;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
/* WooCommerce clearfixes div.product too, and inside a grid that pseudo-element
   is a real item that takes a cell. The same trap as the account page. */
body.single-product div.product::before,
body.single-product div.product::after { content: none; }

body.single-product .cof-wooc { padding-block: 76px 88px; }

/* ------------------------------------------------------------ The gallery --- */

body.single-product div.product div.images img {
  width: 100%;
  height: auto;
  border-radius: var(--cof-r-card);
  display: block;
}
/* The magnifier badge WooCommerce puts over the image. It is a real control, so
   it keeps a real target rather than being hidden. */
body.single-product .woocommerce-product-gallery__trigger {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  top: 16px;
  right: 16px;
  border-radius: 50%;
  background: var(--cof-card);
  color: var(--cof-ink);
  font-size: 17px;
  text-decoration: none;
  box-shadow: 0 2px 10px rgba(26, 17, 10, 0.12);
}

/* ------------------------------------------------------------ The summary --- */

body.single-product div.product .product_title {
  margin: 0;
  font-family: var(--cof-serif);
  font-size: clamp(28px, 3.2vw, 44px);
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: 0.02em;
  color: var(--cof-ink);
}
body.single-product .woocommerce div.product p.price,
body.single-product div.product p.price {
  margin: 0;
  color: var(--cof-ink);
  font-size: 22px;
  font-weight: 500;
}
body.single-product div.product .woocommerce-product-details__short-description {
  color: var(--cof-body);
  font-size: 16px;
  line-height: 1.7;
  max-width: 46ch;
}
body.single-product div.product .woocommerce-product-details__short-description p:last-child { margin-bottom: 0; }

/*
 * Quantity and the button on one row. WooCommerce's own form.cart floats the
 * quantity, which is the same problem in miniature.
 */
body.single-product .woocommerce div.product form.cart,
body.single-product div.product form.cart {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 14px;
  margin: 6px 0 0;
}
body.single-product .woocommerce div.product form.cart div.quantity,
body.single-product div.product form.cart div.quantity { float: none; margin: 0; }
/*
 * The button grows to fit its label and then stops. Left to flex freely it took
 * the whole summary column, which on a wide screen is 768px of ADD TO CART next
 * to a one-line description.
 */
body.single-product .woocommerce div.product form.cart .button,
body.single-product div.product form.cart .button { flex: 0 1 auto; min-width: 220px; max-width: 340px; }
body.single-product div.product form.cart::before,
body.single-product div.product form.cart::after { content: none; }

/* Stock, and the "out of stock" line. */
body.single-product div.product .stock { margin: 0; font-size: 14px; color: var(--cof-body); }
body.single-product div.product .stock.out-of-stock { color: var(--cof-flag); }

/* SKU and category, under a hairline. Small, because it is reference rather than
   selling copy. */
body.single-product div.product .product_meta {
  margin: 8px 0 0;
  padding-top: 18px;
  border-top: 1px solid var(--cof-hairline);
  font-size: 13px;
  line-height: 1.9;
  color: var(--cof-muted);
}
body.single-product div.product .product_meta > span { display: block; }
body.single-product div.product .product_meta a { color: var(--cof-body); text-decoration: underline; text-underline-offset: 3px; }
body.single-product div.product .product_meta a:hover { color: var(--cof-ink); }

/* --------------------------------------------- Single product, responsive --- */

@media (max-width: 900px) {
  body.single-product div.product { grid-template-columns: minmax(0, 1fr); gap: 28px; }
  body.single-product .cof-wooc { padding-block: var(--cof-section) 48px; }
  body.single-product .woocommerce div.product form.cart .button,
  body.single-product div.product form.cart .button { width: 100%; flex: 1 1 100%; }
}

/*
 * The gallery's magnifier badge, at a real target size.
 *
 * WooCommerce writes it at (0,4,2) as
 * `.woocommerce div.product div.images .woocommerce-product-gallery__trigger`,
 * so an earlier attempt at (0,2,1) did nothing and the control measured 36x36,
 * under the 24px WCAG 2.5.8 asks and well under the 44 a finger wants.
 *
 * The second attempt failed for a more interesting reason. `body.single-product
 * .woocommerce div.product ...` looks like it adds specificity and matches
 * nothing at all: this theme removes WooCommerce's own wrapper div, so the only
 * element carrying the `woocommerce` class IS the body, and an element cannot be
 * its own descendant. Both classes are on the same element, so they are written
 * as one compound below, `.woocommerce.single-product`, which matches the body
 * and comes to (0,5,2).
 *
 * The magnifier itself is not a glyph: WooCommerce draws a circle with ::before
 * and its handle with ::after, both absolutely positioned for a 36px box. Growing
 * the box to 44 without moving them leaves the icon 4px off centre, so both are
 * nudged by the same 4px.
 */
.woocommerce.single-product div.product div.images .woocommerce-product-gallery__trigger {
  width: 44px;
  height: 44px;
  top: 16px;
  right: 16px;
  padding: 0;
  background: var(--cof-card);
  box-shadow: 0 2px 10px rgba(26, 17, 10, 0.14);
}
.woocommerce.single-product div.product div.images .woocommerce-product-gallery__trigger::before {
  left: 13px;
  top: 13px;
  border-color: var(--cof-ink);
}
.woocommerce.single-product div.product div.images .woocommerce-product-gallery__trigger::after {
  left: 26px;
  top: 23px;
  background: var(--cof-ink);
}

/*
 * The category link in the product meta. WooCommerce leaves it a plain inline
 * anchor, which measured 35x19: under the 24px minimum, and the only link on the
 * page other than the header and footer.
 */
body.single-product div.product .product_meta a {
  display: inline-block;
  min-height: 24px;
  padding-block: 3px;
}
@media (pointer: coarse) {
  body.single-product div.product .product_meta a { min-height: 44px; padding-block: 12px; }
}
