/* =============================================================================
   20-page-header.css — PAGE HEADER / BREADCRUMB BAR  ("the chapter plate")
   =============================================================================

   Every non-home page opens on this band, so it is composed like a hero, not
   tinted like chrome. The round-one band was a wide gradient carrying two
   words; this one is a two-column editorial plate.

     LEFT   the trail is a HUD line, then the accent rule + kicker, then the
            display title with its accent full stop, then a real sentence.
     RIGHT  A FRAMED PHOTOGRAPH — ~300px tall, bled to the container edge,
            captioned in Fraunces over its own foot scrim. This is the
            counterweight: an object with mass and an image that carries
            meaning, not a floating pill.
     GROUND a second, wider photograph under a five-stop scrim: near-black
            beneath the title, opening to two-thirds tone in the gap between
            the sentence and the plate, so the band is a room the plate
            hangs in.
     FOOT   an index line on the band's bottom rule — the hard facts (counts,
            steps, the sections that live on this page), set behind the
            hero's own 34x1px accent rule so it rhymes with the kicker.

   That is five tiers of information and two photographs per page, all of it
   generated from the WordPress body class, because this workstream owns one
   stylesheet and no template.

   Per page the whole band is four strings and four plate knobs:
     --pb-kicker  --pb-copy  --pb-caption  --pb-index
     --pb-plate / -pos / -opacity / -filter / -flip     the ground
     --pb-tile  / -pos / -filter                        the framed plate

   Markup it must serve (all shipped, none editable from here):
     .page-banner > .container > h1.page-banner-title + nav.breadcrumb
     Shop / product category / tag / brand   (woocommerce/archive-product.php)
     Blog + post archives                    (index.php, archive.php)
     Cart, Checkout, static pages            (page.php)
     My account                              (woocommerce/myaccount/my-account.php)
     Search results                          (search.php)
     Brand archive — h1 nested in an inline-styled flex wrapper with its own
                     eyebrow                 (taxonomy-product_brand.php)
     Single post   — h1 carries an inline font-size:1rem that no rule here can
                     or should beat; the band goes compact instead.
     404 ships `.error-404`, not `.page-banner`, so nothing here applies to it
     and nothing here can break it.

   Loads after main.css and woocommerce.css, so it carries its own media
   queries; main.css breakpoints cannot reach anything declared here.
   ========================================================================== */

/* --- The band ------------------------------------------------------------ */

.page-banner {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: clamp(52px, 5.2vw, 78px) 0 clamp(58px, 5vw, 74px);
  border-bottom: none;              /* replaced by the weighted hairline below */
  background-color: var(--night-2);

  /* Copy. Four strings, so a page is a four-line block further down. */
  --pb-kicker:  "Teaory";
  --pb-copy:    "Loose leaf, teaware, and the quiet craft behind both — gathered slowly, and kept in small quantities.";
  --pb-caption: "First light over the terraces.";
  --pb-index:   "Loose leaf · Teaware · Notes from the table";

  /* The ground: the wider photograph.  It is DARKENED, never desaturated —
     the round-one band pulled saturation to a third and then raised
     brightness, which is the recipe for grey mush: a photograph with its
     colour taken away and its blacks lifted has nothing left to read by.
     Held near its own colour and taken down in exposure instead, it survives
     the scrim as a picture. */
  --pb-plate: url("../../media/journey/05-mountain-road.webp");
  --pb-plate-pos: 50% 30%;
  --pb-plate-opacity: 1;
  --pb-plate-filter: saturate(0.5) contrast(1.18) brightness(0.62) hue-rotate(-12deg);
  --pb-plate-flip: 1;

  /* How far open the scrim's window is over the middle of the band. One
     number per archetype: a bright ground (a green field, a sunset) wants a
     tighter window than a dark one (an interior, a night valley). */
  --pb-window: 0.22;

  /* The plate: the framed photograph on the right. Never faded — this is the
     one image on the page that is meant to be looked at. */
  --pb-tile: url("../../media/journey/01-valley.webp");
  --pb-tile-pos: 50% 62%;
  --pb-tile-size: cover;            /* `auto <n>%` zooms so a crop can be chosen
                                       vertically; at `cover` the plate's own
                                       aspect already fills the frame and the
                                       y-component of -pos does nothing */
  --pb-tile-filter: saturate(0.76) contrast(1.05) brightness(0.9);

  /* The gutter the band's own overlay has to match so the foot index lines up
     with the kicker rule exactly. */
  --pb-gutter: max(
    var(--container-padding),
    calc((100% - var(--container-width)) / 2 + var(--container-padding))
  );
}

/* Layer 1 — the ground photograph. */
.page-banner::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: var(--pb-plate);
  background-repeat: no-repeat;
  background-position: var(--pb-plate-pos);
  background-size: cover;
  opacity: var(--pb-plate-opacity);
  filter: var(--pb-plate-filter);
  /* Some grounds carry their subject in the left half of the frame, which is
     exactly where the scrim goes near-black. Mirroring hands the subject to
     the middle third, where the picture is meant to be read. */
  transform: scaleX(var(--pb-plate-flip));
}

/* Layer 2 — the scrim stack, the grain, the closing hairline, AND the foot
   index. Stacked top-first, as CSS paints background layers. The element is
   inset:0 over the whole band, so its own padding places the index text on
   the container gutter without a second box existing to do it. */
.page-banner::after {
  content: var(--pb-index);
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  display: flex;
  align-items: flex-end;
  padding: 0 var(--pb-gutter) 30px;

  /* the foot index, set behind the hero's 34x1px accent rule */
  font-family: var(--font-primary);
  font-size: 0.7rem;
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  text-indent: 47px;                /* 34px rule + 13px gap, as the kicker */
  color: color-mix(in srgb, var(--ink) 55%, transparent);

  background-image:
    /* the accent rule the index sits behind — content-box origin, so it lands
       on the container gutter whatever the viewport is doing */
    linear-gradient(90deg,
      var(--color-accent) 0%,
      color-mix(in srgb, var(--color-accent) 22%, transparent) 100%),
    /* the foot rail the index hangs under, gutter to gutter */
    linear-gradient(90deg,
      var(--color-border-strong) 0%,
      color-mix(in srgb, var(--color-border) 70%, transparent) 58%,
      transparent 100%),
    /* the closing hairline — brightest under the headline, dissolving right */
    linear-gradient(90deg,
      color-mix(in srgb, var(--color-accent) 34%, transparent) 0%,
      var(--color-border-strong) 24%,
      var(--color-border) 62%,
      transparent 100%),
    /* film grain over the whole plate, so photo and gradient share a surface */
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)' opacity='0.42'/%3E%3C/svg%3E"),
    /* a low green wash pooling under the title, keeping the brand in the dark */
    radial-gradient(56% 128% at 3% 118%,
      color-mix(in srgb, var(--color-primary) 22%, transparent) 0%,
      color-mix(in srgb, var(--color-primary) 5%, transparent) 44%,
      transparent 72%),
    /* the vertical recess: dark under the site header so the sticky bar has
       something to sit on, opening through the middle, closing into the page */
    linear-gradient(180deg,
      color-mix(in srgb, var(--night-2) 78%, transparent) 0%,
      color-mix(in srgb, var(--night-2) 6%, transparent) 40%,
      color-mix(in srgb, var(--night-2) 46%, transparent) 100%),
    /* THE SCRIM.  Near-black under the display type, then a real WINDOW —
       --pb-window, per archetype, typically 0.18–0.30 — across the middle
       third where nothing is set, then closing again so the framed plate on
       the right has an edge to stand against.  The round-one stack never
       went below 0.46 anywhere, which is why the band read as a flat green
       panel with a rumour of a photograph in it. */
    linear-gradient(90deg,
      rgba(9, 15, 11, 0.965) 0%,
      rgba(9, 15, 11, 0.905) 22%,
      rgba(9, 15, 11, calc(var(--pb-window) + 0.30)) 38%,
      rgba(9, 15, 11, var(--pb-window)) 54%,
      rgba(9, 15, 11, var(--pb-window)) 68%,
      rgba(9, 15, 11, calc(var(--pb-window) + 0.34)) 86%,
      rgba(9, 15, 11, 0.72) 100%);
  background-repeat: no-repeat, no-repeat, no-repeat, repeat, no-repeat, no-repeat, no-repeat;
  background-position: left 0 bottom 5px, left 0 bottom 26px, left bottom, 0 0, 0 0, 0 0, 0 0;
  background-size: 34px 1px, 100% 1px, 100% 1px, 180px 180px, auto, auto, auto;
  background-origin: content-box, content-box, border-box, border-box, border-box, border-box, border-box;
  background-blend-mode: normal, normal, normal, soft-light, normal, normal, normal;
}

/* --- Archetype plates ----------------------------------------------------
   Ground + framed plate per page family. Ordered least to most specific, so
   the stacked WordPress body classes resolve the way a reader would expect
   (a cart page is also `page`; a product category is also an archive).
   Ground and plate are never the same photograph on the same page. */

/* The collection — the row of bushes behind, the picked leaf on the wall.
   The crop sits low in the frame on purpose: higher up this photograph puts
   a picker's face directly behind the display type. */
.woocommerce-shop .page-banner,
.tax-product_cat .page-banner,
.tax-product_tag .page-banner,
.post-type-archive-product .page-banner {
  --pb-plate: url("../../media/journey/02-harvest.webp");
  --pb-plate-pos: 50% 94%;
  --pb-plate-opacity: 1;
  --pb-plate-filter: saturate(0.8) contrast(1.12) brightness(0.54);
  --pb-plate-flip: 1;
  --pb-window: 0.30;                /* a bright green field; hold it back */
  --pb-tile: url("../../media/journey/03-drying-house.webp");
  --pb-tile-pos: 46% 78%;
  --pb-tile-filter: saturate(1) contrast(1.08) brightness(1.02);
}

/* The journal — the leaf itself behind, the pour on the wall. */
.blog .page-banner,
.single-post .page-banner,
.archive.category .page-banner,
.archive.tag .page-banner,
.archive.date .page-banner {
  --pb-plate: url("../../media/journey/03-drying-house.webp");
  --pb-plate-pos: 34% 44%;
  --pb-plate-opacity: 1;
  --pb-plate-filter: saturate(0.8) contrast(1.16) brightness(0.68);
  --pb-plate-flip: 1;
  --pb-window: 0.24;
  --pb-tile: url("../../media/journey/06-tea-ceremony.webp");
  --pb-tile-pos: 46% 50%;
  --pb-tile-size: cover;
  --pb-tile-filter: saturate(0.86) contrast(1.06) brightness(1.42);
}

/* The account — the fire the leaf was fixed over, and the field it came from.
   This band used to run 06-tea-ceremony as its ground. That photograph is the
   darkest asset in the set by a distance (mean luma 42/255, ninetieth
   percentile 79) and no exposure curve rescues it: under any scrim at all it
   collapses to a near-black smudge and the band reads as a flat green panel
   with a rumour of a picture in it. 04-fire-and-form is dark too, but it is
   dark WITH HIGHLIGHTS — the kiln mouth carries a real p90 of 127 — so it
   survives the scrim as a photograph instead of as a texture. The window
   opens to 0.30 to let it. */
.woocommerce-account .page-banner,
.page-template-page-wishlist .page-banner {
  --pb-plate: url("../../media/journey/04-fire-and-form.webp");
  --pb-plate-pos: 46% 46%;
  --pb-plate-opacity: 1;
  --pb-plate-filter: saturate(0.92) contrast(1.06) brightness(1.32);
  --pb-plate-flip: 1;
  --pb-window: 0.30;
  --pb-tile: url("../../media/journey/02-harvest.webp");
  --pb-tile-pos: 56% 74%;
  --pb-tile-size: auto 150%;
  --pb-tile-filter: saturate(0.92) contrast(1.06) brightness(0.9);
}

/* The basket — the ridge at dusk.  Cart and checkout are the same valley
   seen twice, from the top and then from the terraces: the pairing is the
   point, so the two crops are deliberately far apart. */
.woocommerce-cart .page-banner {
  --pb-plate: url("../../media/journey/01-valley.webp");
  --pb-plate-pos: 50% 20%;
  --pb-plate-opacity: 1;
  --pb-plate-filter: saturate(0.78) contrast(1.1) brightness(0.6);
  --pb-plate-flip: -1;
  --pb-window: 0.24;
  --pb-tile: url("../../media/journey/03-drying-house.webp");
  --pb-tile-pos: 72% 34%;
  --pb-tile-size: auto 140%;
  --pb-tile-filter: saturate(0.96) contrast(1.06) brightness(0.96);
}

/* Checkout — the road down from the gardens. */
.woocommerce-checkout .page-banner {
  --pb-plate: url("../../media/journey/01-valley.webp");
  --pb-plate-pos: 50% 88%;
  --pb-plate-opacity: 1;
  --pb-plate-filter: saturate(0.82) contrast(1.12) brightness(0.66);
  --pb-plate-flip: 1;
  --pb-window: 0.26;
  --pb-tile: url("../../media/journey/05-mountain-road.webp");
  --pb-tile-pos: 40% 92%;
  --pb-tile-size: auto 168%;
  --pb-tile-filter: saturate(0.62) contrast(1.12) brightness(1.1);
}

/* The makers — the canopy over the gardens, fire and form on the wall. */
.tax-product_brand .page-banner,
.page-template-page-brands .page-banner {
  --pb-plate: url("../../media/journey/02-harvest.webp");
  --pb-plate-pos: 50% 4%;
  --pb-plate-opacity: 1;
  --pb-plate-filter: saturate(0.62) contrast(1.16) brightness(0.4);
  --pb-plate-flip: -1;
  --pb-window: 0.34;
  --pb-tile: url("../../media/journey/04-fire-and-form.webp");
  --pb-tile-pos: 42% 50%;
  --pb-tile-filter: saturate(0.94) contrast(1.02) brightness(1.02);
}

/* Search — everything, from the top of the valley. */
.search .page-banner {
  --pb-plate: url("../../media/journey/05-mountain-road.webp");
  --pb-plate-pos: 50% 78%;
  --pb-plate-opacity: 1;
  --pb-plate-filter: saturate(0.44) contrast(1.2) brightness(0.56) hue-rotate(-12deg);
  --pb-plate-flip: -1;
  --pb-window: 0.20;
  --pb-tile: url("../../media/journey/01-valley.webp");
  --pb-tile-pos: 50% 88%;
  --pb-tile-size: auto 150%;
  --pb-tile-filter: saturate(0.8) contrast(1.06) brightness(0.94);
}

/* --- The composition -----------------------------------------------------
   col 1                                        col 2
   row 1  .                                     breadcrumb (HUD, top right)
   row 2  kicker + display title                the framed plate, spanning
   row 3  the sentence                          rows 2 and 3

   `min-height` lives on the container rather than on the plate so the row
   maths is definite: the 1fr row absorbs the slack and the plate stretches
   into a stable ~300px block instead of a letterbox that changes shape with
   the length of the title.                                                  */

.page-banner .container {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(252px, 25.5vw, 384px);
  grid-template-rows: min-content min-content 1fr;
  align-items: start;
  column-gap: clamp(28px, 3.8vw, 68px);
  row-gap: 0;
  min-height: clamp(276px, 24vw, 358px);
  flex-wrap: nowrap;               /* neutralise the flex rules in main.css */
}

/* --- Breadcrumb: HUD text along the top edge ----------------------------- */

.page-banner .breadcrumb {
  grid-column: 2;
  grid-row: 1;
  justify-self: end;
  align-self: start;
  gap: 9px;
  max-width: 100%;
  margin-bottom: 20px;
  font-size: 0.7rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  /* The terminal crumb is a bare text node in the WooCommerce output, so the
     emphasis has to live on the nav and the ancestors have to step down. */
  color: color-mix(in srgb, var(--ink) 88%, transparent);
}

/* Ancestors: recessive. Alpha rather than `opacity`, so the separator and the
   synthetic crumb below are not multiplied down by an inherited fade. */
.page-banner .breadcrumb a {
  color: color-mix(in srgb, var(--ink) 52%, transparent);
  font-weight: 500;
  text-decoration: none;
  padding-bottom: 4px;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: left bottom;
  background-size: 0% 1px;
  transition:
    color 0.32s cubic-bezier(0.2, 0.75, 0.2, 1),
    background-size 0.42s cubic-bezier(0.2, 0.75, 0.2, 1);
}

.page-banner .breadcrumb a:hover,
.page-banner .breadcrumb a:focus-visible {
  color: var(--color-accent);
  outline: none;
}
.page-banner .breadcrumb a:hover,
.page-banner .breadcrumb a:focus-visible { background-size: 100% 1px; }

.page-banner .breadcrumb .sep {
  color: color-mix(in srgb, var(--ink) 28%, transparent);
  font-size: 0.86rem;
  line-height: 1;
}

/* Where the template does mark the current page, it takes the nav emphasis. */
.page-banner .breadcrumb .current {
  color: color-mix(in srgb, var(--ink) 88%, transparent);
  font-weight: 600;
}

/* The posts page is `is_home()`, which teashop_breadcrumb() answers with a
   lone "Home" and no terminal crumb. The trail is finished here instead:
   a separator inside the anchor, then the current page after it. */
.blog .page-banner .breadcrumb::after {
  content: "Blog";
  color: color-mix(in srgb, var(--ink) 88%, transparent);
  font-weight: 600;
}
.blog .page-banner .breadcrumb a::after {
  content: "\203A";                /* the same "›" the helper prints */
  margin-left: 9px;
  color: color-mix(in srgb, var(--ink) 28%, transparent);
  font-size: 0.86rem;
  font-weight: 500;
}
/* …and the hover rule stops short of that borrowed separator. */
.blog .page-banner .breadcrumb a:hover,
.blog .page-banner .breadcrumb a:focus-visible { background-size: calc(100% - 15px) 1px; }

/* --- The title block -----------------------------------------------------

   `display: flex` is load-bearing. The templates print the heading across
   several lines, so most of these h1s carry trailing whitespace; as inline
   content that whitespace would collapse into a visible gap before the
   accent full stop ("Shop ." instead of "Shop."). Flex items are block
   boxes, so each run's trailing space is dropped.
   The cost is that a heading split across elements — `the_archive_title()`
   emits `Category: <span>Tea</span>` — loses its real space too. Hence the
   pair below: a word-space-sized `column-gap` puts every genuine gap back,
   and the full stop cancels it again with an equal negative margin.
   It also gives the kicker somewhere to live: a full-basis flex item ordered
   ahead of the text, which is exactly where the hero puts it.               */

.page-banner-title {
  grid-column: 1;
  grid-row: 2;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  column-gap: 0.25em;
  row-gap: 0;
  min-width: 0;
  max-width: 13ch;
  margin: 0;
  font-family: var(--font-heading);
  font-size: clamp(3.4rem, 6.6vw, 6.9rem);
  font-weight: 300;
  font-optical-sizing: auto;
  line-height: 0.9;
  /* The hero sets its display at -0.045em and the band was running -0.03em,
     so at 95px the two headlines were 1.4px per letter apart — enough that
     the band read as a lighter, looser cut of the same face. One ratio. */
  letter-spacing: -0.045em;
  color: var(--ink);
  text-wrap: balance;
  overflow-wrap: break-word;        /* a pasted search term can't burst the band */
  text-shadow: 0 6px 44px rgba(3, 7, 4, 0.62);
}

/* Micro-kicker — the hero's signature, 34x1px accent rule and all. */
.page-banner-title::before {
  content: var(--pb-kicker);
  order: -1;
  flex: 0 0 100%;
  margin-bottom: clamp(18px, 1.8vw, 26px);
  padding-left: 47px;               /* 34px rule + 13px gap, as the hero */
  background-image: linear-gradient(90deg,
    var(--color-accent) 0%,
    color-mix(in srgb, var(--color-accent) 26%, transparent) 100%);
  background-repeat: no-repeat;
  background-position: left center;
  background-size: 34px 1px;
  font-family: var(--font-primary);
  font-size: 0.7rem;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--color-text-light);
  text-shadow: none;
  white-space: nowrap;
}

/* The single accent moment, borrowed from the hero's "becomes *tea*." */
.page-banner-title::after {
  content: ".";
  margin-left: -0.25em;             /* cancels the column-gap; see above */
  color: var(--color-accent);
  font-family: inherit;
  font-weight: inherit;
}

/* --- Second tier: one line of real copy ---------------------------------- */

.page-banner .container::after {
  content: var(--pb-copy);
  grid-column: 1;
  grid-row: 3;
  justify-self: start;
  align-self: start;
  max-width: 38ch;
  margin-top: clamp(20px, 2vw, 30px);
  font-family: var(--font-primary);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.62;
  letter-spacing: 0.004em;
  color: color-mix(in srgb, var(--ink) 60%, transparent);
  text-wrap: pretty;
}

/* --- The counterweight: a framed, captioned photograph -------------------
   One element does all of it: the picture is the lower background layer, the
   caption's foot scrim is the upper one, and the caption itself is the
   generated content, dropped to the bottom of the frame by the flex. */

.page-banner .container::before {
  content: var(--pb-caption);
  grid-column: 2;
  grid-row: 2 / -1;
  align-self: stretch;
  justify-self: stretch;
  display: flex;
  align-items: flex-end;
  min-height: 176px;
  padding: 0 clamp(16px, 1.5vw, 22px) clamp(15px, 1.4vw, 20px);
  border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent);
  border-radius: var(--radius-md);
  background-color: var(--night-2);
  background-image:
    /* the caption's own scrim, so the line reads on any crop */
    linear-gradient(180deg,
      rgba(6, 11, 8, 0) 52%,
      rgba(6, 11, 8, 0.34) 70%,
      rgba(6, 11, 8, 0.8) 88%,
      rgba(6, 11, 8, 0.95) 100%),
    var(--pb-tile);
  background-repeat: no-repeat, no-repeat;
  background-position: center, var(--pb-tile-pos);
  background-size: cover, var(--pb-tile-size);
  filter: var(--pb-tile-filter);
  box-shadow:
    0 30px 64px -34px rgba(0, 0, 0, 0.9),
    inset 0 1px 0 color-mix(in srgb, var(--ink) 8%, transparent);
  font-family: var(--font-heading);
  font-size: clamp(0.95rem, 1.02vw, 1.08rem);
  font-weight: 300;
  font-optical-sizing: auto;
  line-height: 1.36;
  letter-spacing: -0.004em;
  color: color-mix(in srgb, var(--ink) 88%, transparent);
  text-shadow: 0 2px 16px rgba(0, 0, 0, 0.8);
  text-wrap: pretty;
}

/* =============================================================================
   PER-PAGE COPY — kicker / sentence / plate caption / foot index.
   Ordered least to most specific, so the stacked WordPress body classes
   resolve the way a reader would expect (a cart page is also `page`).
   ========================================================================== */

/* --- The collection ------------------------------------------------------ */
.woocommerce-shop .page-banner {
  --pb-kicker:  "The Collection";
  --pb-copy:    "Leaf, clay and iron — five hundred and eighty-one pieces, arranged by origin, season and the hand that made them.";
  --pb-caption: "Green leaf, sorted by hand before the kiln.";
  --pb-index:   "581 pieces · 14 categories · Teapots, gaiwan, cups, trays, white and dark tea";
}

.tax-product_cat .page-banner {
  --pb-kicker:  "Collection";
  --pb-copy:    "One corner of the collection — the same sourcing, narrowed to a single shelf.";
  --pb-caption: "Sorted by leaf, long before it reaches the shelf.";
  --pb-index:   "Part of 581 pieces across 14 categories";
}

.tax-product_tag .page-banner {
  --pb-kicker:  "Tagged";
  --pb-copy:    "Everything filed under this tag, newest first, across teas and teaware alike.";
  --pb-caption: "Sorted by leaf, long before it reaches the shelf.";
  --pb-index:   "Part of 581 pieces across 14 categories";
}

.page-template-page-brands .page-banner,
.tax-product_brand .page-banner {
  --pb-kicker:  "Makers";
  --pb-copy:    "The kilns, gardens and workshops behind the collection — and what each of them is known for.";
  --pb-caption: "Fire and form: the wok, held at temperature.";
  --pb-index:   "Every maker in the collection, listed A to Z";
}

/* --- The journal --------------------------------------------------------- */
.blog .page-banner {
  --pb-kicker:  "The Journal";
  --pb-copy:    "Field notes from the harvest, the kiln and the table — how the tea is made, and how to make it well.";
  --pb-caption: "The pour, held steady until the cup is full.";
  --pb-index:   "3 entries · Brewing · Origin · Craft";
}

.archive.category .page-banner,
.archive.tag .page-banner,
.archive.date .page-banner,
.single-post .page-banner {
  --pb-kicker:  "From the Journal";
  --pb-copy:    "Everything filed under this heading, newest first.";
  --pb-caption: "The pour, held steady until the cup is full.";
  --pb-index:   "From the journal · Brewing · Origin · Craft";
}

/* --- Search -------------------------------------------------------------- */
.search .page-banner {
  --pb-kicker:  "Search";
  --pb-copy:    "Everything matching your words — teas, teaware and writing, ranked by how closely they answer.";
  --pb-caption: "First light over the terraces.";
  --pb-index:   "581 pieces and every journal entry indexed";
}

/* --- Commerce utilities -------------------------------------------------- */
.woocommerce-cart .page-banner {
  --pb-kicker:  "Your Basket";
  --pb-copy:    "Everything set aside so far. Quantities are still yours to change, and nothing is reserved until you check out.";
  --pb-caption: "Green leaf, resting before the kiln.";
  --pb-index:   "Step 1 of 2 · Review the basket, then delivery and payment";
}

.woocommerce-checkout .page-banner {
  --pb-kicker:  "Secure Checkout";
  --pb-copy:    "Delivery first, then payment. Nothing is charged until you confirm the order.";
  --pb-caption: "The road down from the gardens.";
  --pb-index:   "Step 2 of 2 · Delivery · Payment · Confirmation";
}

.woocommerce-account .page-banner {
  --pb-kicker:  "Your Account";
  --pb-copy:    "Orders, addresses and the details we keep for you — all of it editable, all of it in one place.";
  --pb-caption: "Picked by hand, the week it was ready.";
  --pb-index:   "Orders · Addresses · Payment details · Account settings";
}

.page-template-page-wishlist .page-banner {
  --pb-kicker:  "Saved";
  --pb-copy:    "The pieces you set aside to think about. They stay here until you move them on.";
  --pb-caption: "Picked by hand, the week it was ready.";
  --pb-index:   "Saved pieces · Move to basket · Keep for later";
}

/* --- Brand archive -------------------------------------------------------
   The template prints its own eyebrow inside an inline-styled flex wrapper,
   so a second kicker would stutter and the h1 is not a grid child. Give the
   wrapper the title's row and stand the kicker down. */
.tax-product_brand .page-banner .container > div {
  grid-column: 1;
  grid-row: 2;
  align-self: start;
  min-width: 0;
}
.tax-product_brand .page-banner-title {
  max-width: 18ch;
}
.tax-product_brand .page-banner-title::before { content: none; }

/* --- Single post ---------------------------------------------------------
   The article prints its own headline below, and the template hard-codes
   font-size:1rem on this h1. Fighting an inline style would only produce the
   same title twice at display size, so the band goes compact: the kicker and
   the trail stay, the heading reads as a caption, and the plate, the
   sentence and the foot index all stand down because the article's own
   hero follows immediately. */
.single-post .page-banner {
  padding: clamp(38px, 3.8vw, 56px) 0 clamp(34px, 3.4vw, 48px);
  --pb-plate-opacity: 0.4;
}
.single-post .page-banner::after {
  content: "";
  padding-bottom: 0;
  background-image:
    linear-gradient(90deg,
      color-mix(in srgb, var(--color-accent) 30%, transparent) 0%,
      var(--color-border-strong) 24%,
      var(--color-border) 62%,
      transparent 100%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--night-2) 84%, transparent) 0%,
      color-mix(in srgb, var(--night-2) 26%, transparent) 60%,
      color-mix(in srgb, var(--night-2) 58%, transparent) 100%),
    linear-gradient(90deg,
      rgba(9, 15, 11, 0.96) 0%,
      rgba(9, 15, 11, 0.8) 60%,
      rgba(9, 15, 11, 0.66) 100%);
  background-repeat: no-repeat, no-repeat, no-repeat;
  background-position: left bottom, 0 0, 0 0;
  background-size: 100% 1px, auto, auto;
  background-origin: border-box, border-box, border-box;
  background-blend-mode: normal, normal, normal;
}
.single-post .page-banner .container {
  grid-template-columns: minmax(0, 1fr) auto;
  min-height: 0;
}
.single-post .page-banner .container::before { content: none; }
.single-post .page-banner .container::after { content: none; }
.single-post .page-banner .breadcrumb { margin-bottom: 18px; }
.single-post .page-banner-title {
  max-width: 52ch;
  font-family: var(--font-primary);
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: 0.01em;
  color: var(--color-text);
  text-shadow: none;
}
.single-post .page-banner-title::before { margin-bottom: 14px; }
.single-post .page-banner-title::after { content: none; }

/* =============================================================================
   BREAKPOINTS — this file loads last, so it carries its own.
   ========================================================================== */

@media (max-width: 1240px) {
  .page-banner .container { grid-template-columns: minmax(0, 1fr) clamp(238px, 27vw, 330px); }
  .page-banner-title { max-width: 12ch; }
  .page-banner .container::after { max-width: 40ch; }
}

@media (max-width: 1024px) {
  .page-banner {
    padding: clamp(50px, 5.4vw, 72px) 0 clamp(66px, 6vw, 84px);
  }
  .page-banner .container {
    grid-template-columns: minmax(0, 1fr) minmax(200px, 30vw);
    min-height: 236px;
    column-gap: 30px;
  }
  .page-banner-title { font-size: clamp(3rem, 6.2vw, 4.4rem); }
  .page-banner .container::after { max-width: 34ch; font-size: 0.95rem; }
  .page-banner::after { font-size: 0.7rem; letter-spacing: 0.12em; }
}

/* Under ~820px the two-column composition stops being honest: there is not
   enough width for a display title AND a frame. The plate becomes a
   full-width letterbox below the copy — still the counterweight, now the
   floor of the band rather than its right-hand wall. */
@media (max-width: 820px) {
  .page-banner {
    padding: 44px 0 84px;
    --pb-plate-opacity: 0.4;
  }
  /* One column, so the index has to hold one line: the rail and the accent
     tick are pinned a fixed distance off the floor, and a wrapped second line
     would be struck through by both. The rail stands down, the tick stays,
     and every index shortens to its headline fact. */
  .page-banner::after {
    background-size: 34px 1px, 0 0, 100% 1px, 180px 180px, auto, auto, auto;
  }
  .page-banner { --pb-index: "Loose leaf · Teaware · Notes"; }
  .woocommerce-shop .page-banner { --pb-index: "581 pieces · 14 categories"; }
  .tax-product_cat .page-banner,
  .tax-product_tag .page-banner { --pb-index: "Part of 581 pieces"; }
  .page-template-page-brands .page-banner,
  .tax-product_brand .page-banner { --pb-index: "Every maker, A to Z"; }
  .blog .page-banner { --pb-index: "3 entries · Brewing · Craft"; }
  .archive.category .page-banner,
  .archive.tag .page-banner,
  .archive.date .page-banner,
  .single-post .page-banner { --pb-index: "From the journal"; }
  .search .page-banner { --pb-index: "581 pieces indexed"; }
  .woocommerce-cart .page-banner { --pb-index: "Step 1 of 2 · Review"; }
  .woocommerce-checkout .page-banner { --pb-index: "Step 2 of 2 · Delivery"; }
  .woocommerce-account .page-banner { --pb-index: "Orders · Addresses · Details"; }
  .page-template-page-wishlist .page-banner { --pb-index: "Saved · Move to basket"; }
  .page-banner .container {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: min-content min-content min-content min-content;
    column-gap: 0;
    min-height: 0;
  }
  .page-banner .breadcrumb {
    grid-column: 1;
    grid-row: 1;
    justify-self: start;
    gap: 7px;
    margin-bottom: 24px;
    letter-spacing: 0.11em;
  }
  .page-banner-title {
    grid-column: 1;
    grid-row: 2;
    max-width: 11ch;
    font-size: clamp(2.7rem, 8.4vw, 3.9rem);
  }
  .page-banner .container::after {
    grid-column: 1;
    grid-row: 3;
    max-width: 44ch;
    margin-top: 18px;
    font-size: 0.95rem;
  }
  .page-banner .container::before {
    grid-column: 1;
    grid-row: 4;
    align-self: start;
    height: clamp(150px, 27vw, 208px);
    min-height: 0;
    margin-top: 28px;
  }
  .single-post .page-banner { padding: 34px 0 32px; }
  .single-post .page-banner .container { grid-template-columns: minmax(0, 1fr); }
  .single-post .page-banner-title { font-size: 0.98rem; max-width: none; }
}

@media (max-width: 560px) {
  .page-banner {
    padding: 34px 0 92px;
    --pb-plate-opacity: 0.34;
  }
  .page-banner .breadcrumb { margin-bottom: 20px; font-size: 0.7rem; }
  .page-banner-title {
    max-width: 10ch;
    font-size: clamp(2.4rem, 11vw, 3.2rem);
    letter-spacing: -0.032em;
  }
  .page-banner-title::before { margin-bottom: 15px; }
  .page-banner .container::after {
    max-width: none;
    margin-top: 16px;
    font-size: 0.92rem;
    line-height: 1.58;
  }
  .page-banner .container::before {
    height: clamp(136px, 40vw, 178px);
    margin-top: 24px;
    padding: 0 15px 13px;
    font-size: 0.95rem;
  }
  .page-banner::after {
    padding-bottom: 24px;
    text-indent: 34px;
    letter-spacing: 0.1em;
    line-height: 1.05;
    background-position: left 0 bottom 5px, left 0 bottom 24px, left bottom, 0 0, 0 0, 0 0, 0 0;
    background-size: 22px 1px, 0 0, 100% 1px, 180px 180px, auto, auto, auto;
  }
  .single-post .page-banner { padding: 28px 0 26px; }
  .single-post .page-banner::after { padding-bottom: 0; }
}

/* Below 400px a character cap only creates ragged two-word lines; let the
   measure be the viewport and keep the size continuous with the rule above. */
@media (max-width: 400px) {
  .page-banner-title { max-width: none; }
  .page-banner-title::before { white-space: normal; }
}

/* Decoration is decoration: keep the ground, drop the motion. */
@media (prefers-reduced-motion: reduce) {
  .page-banner .breadcrumb a { transition: none; }
}
