/*
Theme Name: Ethan Burham Photography
Theme URI: https://ethanburham.com
Author: InnovaERP
Description: Block theme for Ethan Burham's wildlife photography portfolio and print gallery. Ships three style variations: Understory (dark gallery), Field Notes (paper archive), and Blind & Bough (graphic). Palette sampled from Ethan Burham's photographs.
Version: 0.1.0
Requires at least: 6.5
Tested up to: 7.0
Requires PHP: 8.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: burham-photography
Tags: portfolio, photography, block-patterns, full-site-editing, wide-blocks
*/

/* Block themes style through theme.json. Only what the editor cannot express lives here. */

/* Header lockup: text title until a site logo exists, then the logo alone. */
.eb-lockup .wp-block-site-logo:empty{ display:none; }
.eb-lockup:has(.wp-block-site-logo img) .wp-block-site-title{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }
.eb-lockup .wp-block-site-logo img{ max-height:64px; width:auto; display:block; }

.eb-lockup__by{
  font-size: var(--wp--preset--font-size--tiny);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--wp--preset--color--dim);
  font-family: var(--wp--preset--font-family--body);
  font-weight: 500;
  margin-block-start: 1.1rem;
}
.eb-eyebrow{
  font-size: var(--wp--preset--font-size--tiny);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--wp--preset--color--dim);
  font-family: var(--wp--preset--font-family--body);
  font-weight: 500;
}

/* photographs sit flush; the image is the only luminous thing on a dark ground */
.eb-plate img{ width:100%; height:100%; object-fit:cover; display:block; }
.eb-plate--glow img{ box-shadow: 0 0 120px 28px rgb(from var(--wp--preset--color--accent) r g b / .13); }

/* photo grid rendered by [eb_photos] */
.eb-photos{ display:grid; gap:1rem; grid-template-columns:repeat(auto-fill, minmax(min(100%, 260px), 1fr)); margin-block: 2rem; }
.eb-photos figure{ margin:0; }
.eb-photos img{ width:100%; height:auto; display:block; }
.eb-photos__link{ display:block; }
.eb-photos__link:hover img, .eb-photos__link:focus-visible img{ opacity:.88; }
/* Display headings must fit a phone: the variation's mega sizes are not fluid. */
@media (max-width:600px){
  h1.has-display-font-size, .has-display-font-size{ font-size:2.6rem !important; }
  h1.has-mega-font-size, .has-mega-font-size{ font-size:3.2rem !important; }
  h2.has-x-large-font-size{ font-size:1.9rem !important; }
}
/* Dropdown submenus (task 8, 2026-09-28), both the desktop popover and the
   already-expanded copy inside the mobile overlay: verified live (rendered
   markup + computed styles) that core does NOT need this to avoid a white
   dropdown — it already stamps has-background/has-base-background-color and
   has-text-color/has-contrast-color straight onto every
   .wp-block-navigation__submenu-container, propagated from THIS nav's
   overlayBackgroundColor/overlayTextColor (deliberately untouched — that
   pair is what broke the mobile overlay once already on this project), and
   those preset utility classes are !important, which already beats core's
   own white/black :not(.has-background) fallback on its own. What this rule
   does instead is a deliberate shade choice, not a bug fix: it lifts the
   popover to "surface" — the same raised-panel color already used for every
   other dropdown/select on this site (see the WooCommerce select rule
   below) — rather than the flatter "base" it would otherwise inherit, so a
   dropdown panel reads as its own surface against the header instead of
   blending flush into it. !important because it has to beat those same
   !important preset utility classes on specificity (both are !important, so
   specificity decides, and this selector's extra element beats their bare
   class). */
header .wp-block-navigation__submenu-container{
  background-color:var(--wp--preset--color--surface) !important;
  border:1px solid var(--wp--preset--color--line) !important;
  color:var(--wp--preset--color--contrast) !important;
}
header .wp-block-navigation__submenu-container a,
header .wp-block-navigation__submenu-container .wp-block-navigation-item__content{
  color:var(--wp--preset--color--contrast) !important;
}
header .wp-block-navigation__submenu-container a:hover,
header .wp-block-navigation__submenu-container a:focus-visible{
  color:var(--wp--preset--color--accent) !important;
}
/* Header: cart sits in the nav row, same size as the nav text. */
.eb-minicart{ align-self:center; }
.eb-minicart .wc-block-mini-cart__button{ padding:0; color:var(--wp--preset--color--contrast); }
.eb-minicart .wc-block-mini-cart__quantity-badge{ font-size:.6rem; }
/* Gallery frames that have a print product say so. */
.eb-photos__buy{ float:right; color:var(--wp--preset--color--accent); text-decoration:none; letter-spacing:.14em; text-transform:uppercase; font-size:.68rem; }
.eb-photos__buy:hover, .eb-photos__buy:focus-visible{ text-decoration:underline; }
/* WooCommerce on the dark ground: keep its blocks on the theme palette. */
/* Woo hides the single-product gallery until its slider script runs; on deferred JS that is a long blank. One image needs no slider. */
.woocommerce-product-gallery{ opacity:1 !important; }
.woocommerce-product-gallery__image img{ width:100%; height:auto; }
/* Shop sort control and empty-cart icon. */
.woocommerce-ordering select, select.orderby, .wc-block-product-filters select{ background:var(--wp--preset--color--surface); color:var(--wp--preset--color--contrast); border:1px solid var(--wp--preset--color--line); padding:.4rem .6rem; font-size:.8rem; }
.with-empty-cart-icon::before{ content:none !important; display:none !important; }
.wc-block-cart__empty-cart__title svg, .wc-block-cart__empty-cart__title img, .wp-block-woocommerce-empty-cart-block .wp-block-image, .wc-block-cart__empty-cart__title .wc-block-cart__empty-cart__icon{ display:none !important; }
/* Phone header: title left, cart + menu button on the right of the same row. */
@media (max-width:600px){
  header .wp-block-group.alignwide{ flex-wrap:nowrap; align-items:center; }
  header .eb-minicart{ order:2; margin-left:auto; }
  header .wp-block-navigation{ order:3; }
}
.wc-block-components-product-price, .woocommerce-Price-amount{ color:var(--wp--preset--color--contrast); }
.wp-block-woocommerce-product-collection .wp-block-post-title a{ text-decoration:none; }
p.stock.out-of-stock, .wc-block-components-product-stock-indicator{ color:var(--wp--preset--color--dim); font-size:.85rem; letter-spacing:.04em; }
table.variations th, table.variations td{ border:0; padding:.4rem 0; }
table.variations select{ background:var(--wp--preset--color--surface); color:var(--wp--preset--color--contrast); border:1px solid var(--wp--preset--color--line); padding:.45rem .6rem; }
.eb-photos figcaption{
  font-size:.72rem; letter-spacing:.06em; color:var(--wp--preset--color--dim);
  margin-block-start:.5rem;
}
.eb-photos--empty{ color:var(--wp--preset--color--dim); font-size:.9rem; }

/* collection cards in a query loop */
.eb-card__meta{
  font-size: var(--wp--preset--font-size--tiny);
  letter-spacing:.2em; text-transform:uppercase; color:var(--wp--preset--color--dim);
}

/* keyboard focus is always visible */
:where(a, button, input, textarea, summary):focus-visible{
  outline: 2px solid var(--wp--preset--color--accent);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce){
  *{ animation-duration:.001ms !important; transition-duration:.001ms !important; }
}

/* ── tables ──────────────────────────────────────────────────────
   Core ships a boxed grid (1px borders that inherit the text colour) and a
   stripes style hard-coded to #f0f0f0. Both assume a light ground and break
   on ours. Replaced with horizontal rules drawn from the palette, so the
   treatment follows whichever style variation is active.
   Selectors include `table` to out-specify the core block stylesheet.       */
.wp-block-table table{ border-collapse:collapse; width:100%; }
.wp-block-table table :is(td,th){
  border:0;
  border-block-end:1px solid var(--wp--preset--color--line);
  padding:.72rem 0;
  text-align:left;
  vertical-align:baseline;
}
.wp-block-table table thead{ border-bottom:0; }
.wp-block-table table th{
  font-family:var(--wp--preset--font-family--body);
  font-size:.62rem;
  font-weight:600;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--wp--preset--color--dim);
  padding-block-end:.55rem;
}
.wp-block-table table td{
  font-size:.88rem;
  font-variant-numeric:tabular-nums;
  color:var(--wp--preset--color--contrast);
}
.wp-block-table table :is(td,th):last-child{
  text-align:right;
  color:var(--wp--preset--color--dim);
}
/* neutralise the stripes style wherever the class still exists */
.wp-block-table.is-style-stripes{ border-bottom:0; background-color:transparent; }
.wp-block-table.is-style-stripes tbody tr:nth-child(odd){ background-color:transparent; }
.wp-block-table.is-style-stripes table :is(td,th){ border-color:var(--wp--preset--color--line); }

/* captions read as annotation, never as body copy */
.wp-element-caption,
.wp-block-table figcaption{
  color:var(--wp--preset--color--dim);
  font-size:.72rem;
  line-height:1.5;
  margin-block-start:.8rem;
}

/* the prints columns should not collide on narrow screens */
@media (max-width: 781px){
  .wp-block-columns:not(.is-not-stacked-on-mobile){ gap:var(--wp--preset--spacing--30); }
}

/* ---- Home / About sections (2026-08-28 copy pass) ---- */
/* D5: !important — the cover block prints its own min-height inline, which
   otherwise wins above the 781px breakpoint (where the mobile rule below
   already has to shout for the same reason). Fixed alongside the identical
   quirk on .eb-collection__hero. */
.eb-hero{ min-height:min(88vh,900px) !important; }
/* Core's cover CSS is printed after this sheet; win on specificity, not order. */
.wp-block-cover.eb-hero{ justify-content:flex-start; align-items:flex-end; text-align:left; }
.wp-block-cover.eb-hero .wp-block-cover__inner-container{ display:grid; justify-items:start; text-align:left; gap:.6rem; padding-bottom:var(--wp--preset--spacing--40); }
.wp-block-cover.eb-hero .wp-block-cover__inner-container > *{ max-width:none !important; margin-left:0 !important; }
.wp-block-cover.eb-hero .wp-block-buttons{ justify-content:flex-start; }
.wp-block-cover.eb-hero .eb-eyebrow{ color:var(--wp--preset--color--accent); }
.wp-block-cover.eb-band{ text-align:left; }
.wp-block-cover.eb-band .wp-block-cover__inner-container > *{ margin-left:0 !important; }
/* Ledes and quotes sit on the wide left edge, not the centred content column. */
.wp-block-post-content > .eb-lede, .wp-block-post-content > .eb-quote, .wp-block-post-content > .wp-block-buttons{ margin-left:0 !important; }
.eb-hero .wp-block-buttons{ margin-top:.8rem; }
.eb-hero h1{ font-size:clamp(3rem, 8vw, 6.5rem); }
.eb-hero__lede{ max-width:34rem; font-size:1.05rem; color:var(--wp--preset--color--contrast); }
/* Proof strip: four facts in one hairline row, like a license hard card. */
.eb-proof{ display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); border-top:1px solid var(--wp--preset--color--line); border-bottom:1px solid var(--wp--preset--color--line); }
.eb-proof > *{ padding:1.1rem 1.2rem 1.1rem 0; margin:0; border-right:1px solid var(--wp--preset--color--line); }
.eb-proof > *:last-child{ border-right:0; }
.eb-proof > * + *{ padding-left:1.2rem; }
.eb-proof__k{ display:block; font-size:var(--wp--preset--font-size--tiny); letter-spacing:.2em; text-transform:uppercase; color:var(--wp--preset--color--dim); margin-bottom:.35rem; }
.eb-proof__v{ font-size:1rem; color:var(--wp--preset--color--contrast); }
@media (max-width:700px){ .eb-proof > *{ border-right:0; border-bottom:1px solid var(--wp--preset--color--line); padding-left:0; } .eb-proof > *:last-child{ border-bottom:0; } }
/* Bands: full-bleed photo with copy pinned to one side. */
.eb-band{ min-height:min(70vh,640px); }
.eb-band .wp-block-cover__inner-container{ max-width:1280px; }
.eb-band__copy{ max-width:30rem; background:color-mix(in srgb, var(--wp--preset--color--base) 82%, transparent); padding:1.6rem 1.8rem; }
.eb-band__copy p{ color:var(--wp--preset--color--contrast); }
.eb-band__copy .wp-block-buttons{ margin-top:1rem; }
/* Section headings in body sections stay smaller than the hero. */
.eb-section h2{ font-size:var(--wp--preset--font-size--x-large); margin-bottom:.4rem; }
.eb-section > .eb-eyebrow{ margin-bottom:.2rem; }
.eb-lede{ font-size:1.12rem; max-width:44rem; color:var(--wp--preset--color--contrast); }
/* Follow: videos + Instagram + Patreon on one row on wide screens. */
.eb-follow .wp-block-embed{ margin:0; }
.eb-follow .wp-block-embed iframe{ width:100%; aspect-ratio:16/9; height:auto; }
.eb-follow__meta{ font-size:var(--wp--preset--font-size--small); color:var(--wp--preset--color--dim); }
/* Prints split: table stays compact next to a photograph. */
.eb-split .wp-block-table table{ font-size:.9rem; }
.eb-split .wp-block-table td, .eb-split .wp-block-table th{ padding:.45rem 0; }
/* About chapters */
.eb-chapter{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.2fr); gap:var(--wp--preset--spacing--30); align-items:center; }
.eb-chapter:nth-of-type(even){ grid-template-columns:minmax(0,1.2fr) minmax(0,1fr); }
.eb-chapter:nth-of-type(even) > figure{ order:2; }
.eb-chapter figure{ margin:0; }
.eb-chapter img{ width:100%; height:auto; display:block; }
.eb-quote{ font-family:var(--wp--preset--font-family--editorial); font-size:clamp(1.4rem,2.6vw,2rem); line-height:1.25; color:var(--wp--preset--color--contrast); max-width:36ch; border-left:3px solid var(--wp--preset--color--accent); padding-left:1rem; margin:0; }
.eb-states{ columns:3; column-gap:1.5rem; font-size:.92rem; color:var(--wp--preset--color--dim); }
@media (max-width:700px){ .eb-chapter, .eb-chapter:nth-of-type(even){ grid-template-columns:1fr; } .eb-chapter:nth-of-type(even) > figure{ order:0; } .eb-states{ columns:2; } }
.eb-teaser{ display:grid; gap:1rem; max-width:48rem; }
.eb-teaser__cover{ width:100%; height:auto; display:block; opacity:.85; }
.eb-teaser__lede{ color:var(--wp--preset--color--dim); }
/* Gallery frames offer a full-resolution download to entitled patrons, next to the buy link. */
.eb-photos__dl{ float:right; margin-right:1rem; color:var(--wp--preset--color--contrast); text-decoration:none; letter-spacing:.14em; text-transform:uppercase; font-size:.68rem; border-bottom:1px solid var(--wp--preset--color--accent); }

/* Footer: the Poorman Media company mark, blended onto the ground (the PNG has a black background). */
.eb-footer__brand{ gap:1rem; }
.eb-footer__logo{ margin:0; }
.eb-footer__logo img{ display:block; width:96px; height:96px; mix-blend-mode:lighten; opacity:.9; }
.eb-footer__logo a:hover img, .eb-footer__logo a:focus-visible img{ opacity:1; }

/* Patreon header link, rendered in front of the mini-cart while the feature is on. */
.eb-patreon-link{ font-size:var(--wp--preset--font-size--tiny); letter-spacing:.18em; text-transform:uppercase; color:var(--wp--preset--color--dim); align-self:center; margin-right:1.2rem; }
.eb-patreon-link a{ color:var(--wp--preset--color--contrast); text-decoration:none; }

/* Home: the newest frames, larger than a collection card and edge to edge. */
.eb-photos--latest{ grid-template-columns:repeat(auto-fill, minmax(min(100%, 320px), 1fr)); gap:1.2rem; margin-block:0; }
.eb-photos--latest figure{ margin:0; overflow:hidden; }
.eb-photos--latest img{ width:100%; height:100%; aspect-ratio:3/2; object-fit:cover; display:block; transition:opacity .2s ease; }
.eb-photos--latest a:hover img, .eb-photos--latest a:focus-visible img{ opacity:.88; }
/* Collection cards: one consistent crop so a row reads as a row. */
.wp-block-query .wp-block-post-featured-image img{ aspect-ratio:3/2; object-fit:cover; width:100%; }

/* ---- Layout corrections (2026-09-27 visual review) ---- */

/* Short pages (Contact) were drawing the footer across the middle of the
   viewport with dead space beneath it. Push it to the bottom without pinning
   it there, so long pages are unaffected. */
.wp-site-blocks{ display:flex; flex-direction:column; min-height:100dvh; }
.wp-site-blocks > main{ flex:1 0 auto; }

/* Running prose gets a reading measure. Only top-level paragraphs and lists are
   capped: anything inside columns is already constrained by its column, and the
   hero, tables and galleries still use the full 1280px. About is nine
   paragraphs of Ethan's own writing and was setting ~150 characters a line. */
.wp-block-post-content > p,
.wp-block-post-content > ul,
.wp-block-post-content > ol{ max-width:44rem; margin-left:0 !important; margin-right:auto !important; }

/* The phone header repeated the hero word for word and cost 230px before any
   photograph. The hero says it better and says it first. */
@media (max-width: 781px){
  .eb-lockup .eb-eyebrow{ display:none; }
}

/* Phone: finger-sized controls, and the collections in view without scrolling. */
@media (max-width: 600px){
  /* The hero ended at 714px of an 844px screen, putting the first collection
     just below the fold. Ethan asked for the collections to start immediately. */
  /* The cover block writes its own min-height inline, so this has to shout. */
  .wp-block-cover.eb-hero{ min-height:min(62vh,540px) !important; }

  /* The cart rendered a 14px hit box and the menu button 24px. Both are now a
     fingertip, without moving the glyphs themselves. */
  header .eb-minicart button,
  header .wp-block-navigation__responsive-container-open,
  .wp-block-navigation__responsive-container-close{
    min-width:44px; min-height:44px;
    display:flex; align-items:center; justify-content:center;
  }

  /* Footer links sat 12px tall with no space between them. */
  footer .wp-block-paragraph a, footer p a{ display:inline-block; padding-block:.45rem; }
}

/* Standard WP pattern: visually hidden but read by a screen reader. Nothing in
   this theme has needed one before the Photo page's unavailable-size wording. */
.screen-reader-text{
  border:0; clip:rect(1px,1px,1px,1px); clip-path:inset(50%);
  height:1px; width:1px; overflow:hidden; position:absolute !important;
  word-wrap:normal !important; margin:-1px; padding:0;
}

/* ---- Photo page (task 9, 2026-09-28) ---- */
/* A block in the main group's constrained layout gets margin-left/right:auto from
   core (centering the box) whenever it is narrower than the content width — which
   this is, deliberately, for a comfortable reading measure. Left-pin it instead,
   same as .wp-block-post-content > p / .eb-lede above, or it reads as a stray
   centred fragment next to a left-aligned title and eyebrow. */
.eb-photo__note{ max-width:44rem; margin-left:0 !important; margin-right:auto !important; }
.eb-photo__collection-link{ margin-top:.4rem; }
.eb-photo__collection-link a{
  color:var(--wp--preset--color--dim); text-decoration:none;
  font-size:var(--wp--preset--font-size--small); letter-spacing:.04em;
}
.eb-photo__collection-link a:hover, .eb-photo__collection-link a:focus-visible{ color:var(--wp--preset--color--accent); }
.eb-photo__unavailable{ color:var(--wp--preset--color--dim); }
/* Reserved for the crop/material builder and room-view preview (not built yet). */
.eb-photo__builder:empty{ display:none; }

/* The price ladder: every size against every medium. Raw shortcode output, so it
   gets its own rules rather than relying on the wp:table block styling above. */
.eb-print-table{ width:100%; border-collapse:collapse; margin-block:1rem; }
.eb-print-table th, .eb-print-table td{
  text-align:left; padding:.55rem .75rem .55rem 0;
  border-block-end:1px solid var(--wp--preset--color--line);
  font-variant-numeric:tabular-nums;
}
.eb-print-table thead th{
  font-family:var(--wp--preset--font-family--body);
  font-size:.62rem; font-weight:600; letter-spacing:.18em; text-transform:uppercase;
  color:var(--wp--preset--color--dim);
}
.eb-print-table tbody th{ font-weight:500; color:var(--wp--preset--color--contrast); white-space:nowrap; }
.eb-print-table tbody td{ color:var(--wp--preset--color--contrast); }
/* A size this file cannot fill: the whole row gets a visible tint so it reads as
   a different row at a glance, not just on close reading — an em dash alone was
   indistinguishable from "fits, but nothing is priced yet" once every cell in a
   pre-launch table is a dash. The cell itself never says "—"; see eb_print_table_html(). */
.eb-print-table__unavailable{
  background:color-mix(in srgb, var(--wp--preset--color--line) 28%, transparent);
}
.eb-print-table__unavailable th{
  color:var(--wp--preset--color--dim);
  text-decoration:line-through;
  text-decoration-color:var(--wp--preset--color--line);
}
.eb-print-table__na{
  color:var(--wp--preset--color--dim);
  font-style:italic;
  font-size:.82rem;
}
/* Fits, but no product is priced yet (pre-launch): a positive, honest label —
   never a blank cell that would read as broken, and never an invented price. */
.eb-print-table__soon{
  display:inline-block;
  color:var(--wp--preset--color--accent);
  font-size:.66rem;
  font-weight:600;
  letter-spacing:.1em;
  text-transform:uppercase;
}
.eb-print-table__legend{
  color:var(--wp--preset--color--dim); font-size:.78rem; margin-top:.6rem;
}
.eb-print-table__none{ color:var(--wp--preset--color--dim); }
/* ---- Photograph page, two columns (2026-09-28) ---- */
.eb-photo__meta{ display:flex; flex-direction:column; gap:.9rem; }
.eb-photo__plate img{ width:100%; height:auto; display:block; }
.eb-crumbs{ font-size:.72rem; letter-spacing:.08em; text-transform:uppercase; color:var(--wp--preset--color--dim); }
.eb-crumbs a{ color:var(--wp--preset--color--dim); text-decoration:none; }
.eb-crumbs a:hover, .eb-crumbs a:focus-visible{ color:var(--wp--preset--color--contrast); text-decoration:underline; }
.eb-photo__where{ color:var(--wp--preset--color--dim); font-size:1rem; margin:0; }
.eb-photo__tags{ font-size:.78rem; color:var(--wp--preset--color--dim); margin:0; }
.eb-photo__tags a{ color:var(--wp--preset--color--accent); text-decoration:none; }
.eb-photo__tags a:hover, .eb-photo__tags a:focus-visible{ text-decoration:underline; }
@media (max-width: 781px){
  /* Photograph first, then everything about it. */
  .eb-photo{ flex-wrap:wrap !important; }
  .eb-photo__plate{ flex-basis:100% !important; }
  .eb-photo__meta{ flex-basis:100% !important; }
}

/* ---- Collection page hub (task 4, 2026-09-28) ---- */
/* Shorter than the home eb-hero (88vh): a species page's job is to get a visitor
   into the grid, not hold them on a splash panel. Inherits eb-hero's cover layout
   (bottom-left content, eyebrow accent colour) rather than inventing a second look. */
/* D5: !important for the same reason as .eb-hero above — the cover block's
   inline min-height otherwise wins above the 781px breakpoint. */
.eb-collection__hero{ min-height:min(46vh,420px) !important; }
@media (max-width: 781px){
  .eb-collection__hero{ min-height:min(38vh,320px) !important; }
}

/* ---- Size chart (task 5, 2026-09-28) ---- */
/* Bars drawn at true relative width (eb_size_chart_rows()'s `scale`), so the
   geometry can never drift from EB_PRINT_SIZES. The label is a flex item with
   its own content width plus white-space:nowrap — the same fault the print
   table above had at 390px ("12 ×" / "18″" splitting across lines) is
   structurally impossible here, and the fix there is the nowrap rule just
   above this block. */
.eb-size-chart{ display:flex; flex-direction:column; gap:.65rem; margin-block:1.2rem; max-width:34rem; }
.eb-size-chart__row{ display:flex; align-items:center; gap:.85rem; }
.eb-size-chart__label{
  flex:0 0 auto; white-space:nowrap;
  font-variant-numeric:tabular-nums; font-size:.85rem;
  color:var(--wp--preset--color--contrast);
}
.eb-size-chart__track{
  flex:1 1 auto; min-width:0; height:1.35rem;
  background:color-mix(in srgb, var(--wp--preset--color--line) 28%, transparent);
  border-radius:2px; overflow:hidden;
}
.eb-size-chart__bar{ display:block; height:100%; background:var(--wp--preset--color--accent); }
@media (max-width:480px){
  .eb-size-chart__label{ font-size:.78rem; }
  .eb-size-chart__row{ gap:.6rem; }
}

/* ---- Room composite (task 6, 2026-09-28) ---- */
/* Nothing has been printed yet, so this is a visualisation, not a photograph
   of a delivered print (eb_room_html() says so in its own caption too). The
   frame's width is the one number that has to stay honest: for a landscape
   photograph it's eb_room_scale_long_edge() * 100% of .eb-room__scene; a
   portrait one computes its own short-edge fraction directly instead (that
   function is long-edge-only by contract). The frame's aspect-ratio is the
   two edges from eb_print_size_inches() for the size actually being shown,
   ordered to match the photograph's own orientation — both computed
   server-side, never hand-tuned here.
   The wall/floor split and the low fixed silhouette are the minimum a glance
   needs to read this as "a wall", not just "a framed rectangle on a card". */
.eb-room{ margin-block:1.4rem; }
.eb-room__scene{
  position:relative;
  width:100%;
  aspect-ratio:16/10;
  border-radius:3px;
  overflow:hidden;
  background:var(--wp--preset--color--surface);
}
.eb-room__wall{
  position:absolute; inset:0; bottom:23%;
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--wp--preset--color--surface) 100%, transparent) 0%, color-mix(in srgb, var(--wp--preset--color--base) 55%, var(--wp--preset--color--surface) 45%) 100%);
}
.eb-room__wall::after{
  /* baseboard */
  content:""; position:absolute; left:0; right:0; bottom:0; height:3px;
  background:var(--wp--preset--color--line);
}
.eb-room__floor{
  position:absolute; left:0; right:0; bottom:0; height:23%;
  background:color-mix(in srgb, var(--wp--preset--color--base) 78%, var(--wp--preset--color--line) 22%);
}
/* The frame (#161512) and the mat (#f2f0e8) are deliberately literal hex, not
   theme tokens: they represent a physical wood frame and a paper mat, not
   themed UI chrome, so they should not shift with a future palette edit the
   way --wp--preset--color--* values are meant to. Everything else in this
   block (wall, floor, furniture, caption) IS themed and uses the palette. */
.eb-room__frame{
  position:absolute; left:50%; top:37%; transform:translate(-50%,-50%);
  background:#161512;
  padding:3.2%;
  box-shadow:0 1.6rem 3.2rem rgba(0,0,0,.55), 0 0 0 1px rgba(230,228,218,.05);
}
.eb-room__mat{
  background:#f2f0e8;
  padding:6%;
  line-height:0;
}
.eb-room__mat img{ width:100%; height:100%; object-fit:cover; display:block; }
.eb-room__furniture{
  /* A low, fixed-height silhouette (a console table) — not scaled with the
     print — so the eye has a second, familiar reference for how big the
     print really is, the way a real room photo would. */
  position:absolute; left:50%; bottom:0; transform:translateX(-50%);
  width:min(30%,220px); height:9%;
  background:color-mix(in srgb, var(--wp--preset--color--line) 65%, var(--wp--preset--color--base) 35%);
  border-radius:2px 2px 0 0;
}
.eb-room__caption{
  margin-top:.7rem;
  font-size:.8rem;
  color:var(--wp--preset--color--dim);
}
@media (max-width:480px){
  .eb-room__scene{ aspect-ratio:4/3.4; }
  .eb-room__caption{ font-size:.74rem; }
}

/* ---- Home: page-family index + feature blocks (task 7, 2026-09-28) ---- */
/* Everything above .eb-latest (hero, collections grid, latest strip) is
   unchanged. This block only styles what Task 7 appends below it, scoped
   under .eb-home-more so it cannot touch the existing sections' spacing. */
.eb-home-more > .eb-section{ border-top:1px solid var(--wp--preset--color--line); padding-top:var(--wp--preset--spacing--40); }
.eb-home-more > .eb-section:first-child{ border-top:0; padding-top:0; }

/* Pill index: plain outlined links, no images, no button fill. */
.eb-pill-index{ display:flex; flex-wrap:wrap; gap:.6rem; margin-block:1.1rem 0; }
.eb-pill{
  display:inline-block; padding:.5rem 1.1rem;
  border:1px solid var(--wp--preset--color--line); border-radius:999px;
  color:var(--wp--preset--color--contrast); text-decoration:none;
  font-size:.85rem; letter-spacing:.02em;
  transition:border-color .15s ease, color .15s ease;
}
.eb-pill:hover, .eb-pill:focus-visible{ border-color:var(--wp--preset--color--accent); color:var(--wp--preset--color--accent); }

/* The two material feature blocks reuse .eb-chapter (About page, alternating
   figure/copy grid) with an [eb_room] composite standing in for the figure —
   the room view already IS a <figure>, so no extra wrapper is needed. The
   two .eb-chapter divs must stay DIRECT siblings (no element between them)
   for :nth-of-type(even) to alternate them correctly. */
.eb-materials .eb-chapter{ margin-block:1.6rem; }
.eb-materials .eb-chapter:first-of-type{ margin-top:1.4rem; }

@media (max-width:480px){
  .eb-pill{ padding:.42rem .9rem; font-size:.8rem; }
}

/* ---- Patreon, surfaced (task 9, 2026-09-28) ---- */
/* Both render only when burham-patreon is switched on and configured; while it
   is off (today, and until Ethan sends credentials) eb_early_access_note_html()
   and eb_patreon_discount_note_html() return an empty string and neither
   selector below ever matches anything on the page. */
.eb-early, .eb-patreon-discount{
  color:var(--wp--preset--color--dim);
  font-size:.9rem;
  margin:.6rem 0 0;
}
.eb-patreon-discount a{ color:var(--wp--preset--color--accent); text-decoration:none; }
.eb-patreon-discount a:hover, .eb-patreon-discount a:focus-visible{ text-decoration:underline; }

/* ---- The Films page's social strip (task 10, 2026-09-28) ---- */
/* eb_social_strip_html() renders nothing while both feeds have nothing to
   show, so .eb-social itself never appears empty on the page — there is no
   "empty state" rule to write here on purpose. */
.eb-social{ margin-block:1.6rem; }
.eb-social__videos{
  display:grid;
  gap:1rem;
  grid-template-columns:repeat(auto-fill, minmax(min(100%, 260px), 1fr));
  margin-block:1rem;
}
.eb-yt-facade{
  position:relative;
  display:block;
  aspect-ratio:4/3;
  overflow:hidden;
  border-radius:2px;
  background:var(--wp--preset--color--contrast);
}
.eb-yt-facade img{ width:100%; height:100%; object-fit:cover; display:block; }
.eb-yt-facade__play{
  position:absolute; inset:0;
  display:flex; align-items:center; justify-content:center;
}
.eb-yt-facade__play::after{
  content:"";
  width:3.2rem; height:3.2rem;
  border-radius:50%;
  /* D4: derived from the dark-ground token (--wp--preset--color--base,
     #0D100D) rather than a hardcoded rgb() of the same value, so this stays
     correct if that token ever changes. */
  background:color-mix(in srgb, var(--wp--preset--color--base) 55%, transparent);
  display:block;
  position:absolute;
}
.eb-yt-facade__play::before{
  content:"";
  width:0; height:0;
  border-style:solid;
  border-width:.65rem 0 .65rem 1.05rem;
  border-color:transparent transparent transparent var(--wp--preset--color--contrast);
  position:relative;
  left:.15rem;
}
.eb-yt-facade:hover .eb-yt-facade__play::before, .eb-yt-facade:focus-visible .eb-yt-facade__play::before{
  border-left-color:var(--wp--preset--color--accent);
}
.eb-yt-facade iframe{ width:100%; height:100%; display:block; border:0; }
.eb-social__more{ font-size:.9rem; }
.eb-social__more a{ color:var(--wp--preset--color--accent); text-decoration:none; }
.eb-social__more a:hover, .eb-social__more a:focus-visible{ text-decoration:underline; }
