/* ===========================================================================
   URSY.AD estate advert units — v3 skin
   Replaces the 67 rules in current-ad.css. Lift this file wholesale into
   theme/ursy-io/assets/css/site.css.

   MARKUP CHANGES: none. Same elements, same child order, same class names
   (.estate-ad, -label, -chip, -advertiser, -link, -imgwrap, -copy, -headline,
   -body, -ctarow, -price, -cta, -provenance, -anchor, -anchor-link, -powered).
   No new wrappers, no renames.

   ONE RENDERER CHANGE became THREE (all one-liners):
   1. Feed the 300x250 MPU the square image_small crop instead of the
      landscape image crop — the creative now sits in a 112px left column and
      the -sq crop fills it; the 2.3:1 -mpu crop renders too small there.
   2. The advertiser name becomes a link: swap the -advertiser <span> for
      <a class="estate-ad-advertiser" href="https://teas.co.uk/"
         rel="sponsored nofollow noopener">teas.co.uk</a>.
   3. Nothing else — the whole-card click and the Powered-by chip are pure
      CSS on the existing markup.

   HOW THE OVERRUN IS FIXED
   Each unit is now one CSS grid on .estate-ad with explicit rows:
   label / link / provenance. The <a> is itself a grid, so the image, copy and
   price+CTA row sit in declared tracks. The copy track is minmax(0,1fr) with
   overflow:hidden, so long titles truncate inside their own track and can
   never push into the price/CTA row — which is pinned by the grid, not by the
   copy above it. Boxes are height (not min-height) at the exact IAB size, so
   content can never grow the reserved box. CLS stays 0.

   ALSO CHANGED
   - Label and provenance are in flow everywhere (no position:absolute), so
     nothing overlaps on 728x90.
   - Provenance now shows on 320x100 too (rule 5); "No tracking" is dropped
     there for space, "Powered by URSY.AD" stays.
   - Advertiser name now shows on 160x600 (was display:none — rule 1 needs it).
   - Pack shots use object-fit:contain on an ivory plate, at 1:1 scale. The old
     cover + scale(1.22) cropped into the product; that was the main ugliness.
   - The 3px accent bar along the top edge is the URSY.AD frame signature —
     one shared device that marks any unit as a paid slot in both themes.
   - The anchored unit gets an accent arrow via ::after (CSS content, no new
     markup). Swap it for a real element if you'd rather it be in the DOM.

   PER-SPONSOR ACCENT (sponsor-agnostic, CSP-safe: no inline styles)
   The skin takes its accent from --estate-ad-accent. Default is the URSY.AD
   amber. For a future advertiser, add one class and put it on the unit:
       .estate-ad-sponsor-acme { --estate-ad-accent: #2f6fd0; }
   Nothing else needs to change.
   =========================================================================== */

:root {
  --estate-ad-accent: #f2c65c;
}

/* --- shared card ---------------------------------------------------------- */

.estate-ad {
  --ad-accent: var(--estate-ad-accent, #f2c65c);
  --ad-accent-ink: #1a1405;
  --ad-ink: #14161d;
  --ad-line: rgba(255, 255, 255, .11);
  --ad-title: #f6f7f9;
  --ad-body: #a4a7b2;
  --ad-meta: #767b8a;
  --ad-plate: #f7f6f2;
  position: relative;
  box-sizing: border-box;
  display: grid;
  margin: 18px auto;
  overflow: hidden;
  border: 1px solid var(--ad-line);
  border-radius: 12px;
  background: var(--ad-ink);
  color: var(--ad-title);
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  box-shadow: 0 1px 2px rgba(10, 11, 15, .34), 0 10px 26px rgba(10, 11, 15, .2);
}

/* the URSY.AD frame signature */
.estate-ad::before,
.estate-ad-anchor::before {
  content: "";
  position: absolute;
  top: 0;
  inset-inline: 0;
  height: 3px;
  background: var(--ad-accent);
  pointer-events: none;
}

.estate-ad *,
.estate-ad-anchor * {
  box-sizing: border-box;
}

/* --- advert label (rule 1: ADVERT + advertiser, always legible) ----------- */

.estate-ad-label {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .1em;
  line-height: 1.4;
  text-transform: uppercase;
  color: var(--ad-meta);
}

.estate-ad-chip {
  flex: none;
  padding: 2px 6px 1px;
  border: 1px solid var(--ad-accent);
  border-radius: 4px;
  background: transparent;
  color: var(--ad-accent);
  font-weight: 800;
  letter-spacing: .14em;
}

.estate-ad-advertiser {
  position: relative;
  z-index: 2;
  min-width: 0;
  overflow: hidden;
  color: #ced1d9;
  font-weight: 700;
  letter-spacing: .05em;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-decoration: none;
}

a.estate-ad-advertiser:hover {
  color: var(--ad-accent);
  text-decoration: underline;
}

/* --- the link is a grid; the copy track is what clips ---------------------- */

.estate-ad-link {
  display: grid;
  min-width: 0;
  min-height: 0;
  color: inherit;
  text-decoration: none;
}

/* the whole unit is the product link: the <a> stretches over the card.
   The advertiser and Powered-by links sit above it on z-index 2. */
.estate-ad-link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

.estate-ad-link:focus-visible,
.estate-ad-anchor-link:focus-visible {
  outline: 2px solid var(--ad-accent);
  outline-offset: 3px;
  border-radius: 6px;
}

.estate-ad-copy {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
}

.estate-ad-headline {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  color: var(--ad-title);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -.006em;
  line-height: 1.24;
  text-wrap: pretty;
}

.estate-ad-body {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  color: var(--ad-body);
  font-size: 12px;
  font-weight: 400;
  line-height: 1.42;
}

/* the two empty-body cards collapse cleanly instead of leaving a gap */
.estate-ad-body:empty {
  display: none;
}

/* --- price + CTA: pinned by the grid, never by the copy ------------------- */

.estate-ad-ctarow {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.estate-ad-price {
  margin-inline-end: auto;
  color: #fff;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.estate-ad-cta {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border-radius: 8px;
  background: var(--ad-accent);
  color: var(--ad-accent-ink);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .005em;
  white-space: nowrap;
  transition: background .14s ease, transform .14s ease;
}

.estate-ad-cta i {
  font-style: normal;
  transition: transform .14s ease;
}

.estate-ad-link:hover .estate-ad-cta {
  background: #ffd982;
}

.estate-ad-link:hover .estate-ad-cta i {
  transform: translateX(2px);
}

/* --- provenance (rule 5) -------------------------------------------------- */

.estate-ad-provenance {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
  overflow: hidden;
  color: var(--ad-meta);
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: .09em;
  line-height: 1.5;
  text-transform: uppercase;
  white-space: nowrap;
}

/* "no tracking" stays, but as a whisper.

   REVISED 11 September 2026. The whisper was inaudible: at opacity .45 this
   line renders at 1.84:1 on the dark plate and 1.79:1 on the light one, against
   4.5:1 for AA. It is 8.5px text, and it is the privacy claim - the one line
   telling a reader this advert does not track them. A promise nobody can read
   is not a promise.

   MEASURED, all four combinations, on the live plate rather than reasoned about:

                          on dark plate   on light plate
     --ad-meta  .45           1.84             1.79
     --ad-meta  1.00          4.28             4.45     <- still fails BOTH
     --ad-body  .45           2.52             2.11
     --ad-body  .85           5.77             5.04     <- chosen

   Note the second row: simply deleting the opacity does NOT fix this. The meta
   colour is too close to both grounds at this size, which is why the fix is the
   colour AND the fade together.

   .85 rather than 1 keeps the line quieter than the copy above it, which is what
   the whisper was for; the legibility comes from the colour instead. */
.estate-ad-provenance > span {
  color: var(--ad-body);
  opacity: .85;
  font-weight: 500;
}

/* Powered by URSY.AD is the feature — it gets its own chip */
.estate-ad-powered {
  position: relative;
  z-index: 2;
  flex: none;
  padding: 2px 6px 1px;
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 4px;
  color: #a2a8b6;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}

.estate-ad-powered:hover {
  color: var(--ad-accent);
  border-color: var(--ad-accent);
}

/* --- creative plate: pack shot shown whole, on light ---------------------- */

.estate-ad-imgwrap {
  position: relative;
  display: block;
  overflow: hidden;
  padding: 6px;
  border: 0;
  border-radius: 9px;
  background: var(--ad-plate);
  box-shadow: inset 0 0 0 1px rgba(12, 14, 20, .12);
}

.estate-ad-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: var(--estate-ad-img-fit, cover);
  transform: none;
  /* letterbox areas paint plate-ivory, never whatever sits behind */
  background: var(--ad-plate);
}

/* =====  300x250 MPU  ======================================================
   Image moves to a left column, so the copy gets 149px of height instead of
   38px. Headline 3 lines + body 4 lines both fit the worst case.            */

.estate-ad-300x250 {
  width: 300px;
  height: 250px;
  max-width: 100%;
  padding: 10px 12px 9px;
  grid-template-rows: auto minmax(0, 1fr) auto;
  row-gap: 8px;
}

.estate-ad-300x250 .estate-ad-link {
  grid-template-columns: 112px minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) auto;
  column-gap: 11px;
  row-gap: 9px;
}

.estate-ad-imgwrap-300x250 {
  grid-column: 1;
  grid-row: 1;
  width: 112px;
  height: 100%;
}

.estate-ad-300x250 .estate-ad-copy {
  grid-column: 2;
  grid-row: 1;
}

.estate-ad-300x250 .estate-ad-ctarow {
  grid-column: 1 / -1;
  grid-row: 2;
}

.estate-ad-300x250 .estate-ad-headline {
  -webkit-line-clamp: 3;
}

.estate-ad-300x250 .estate-ad-body {
  -webkit-line-clamp: 4;
}

/* =====  728x90 leaderboard  ===============================================
   Row 1 is a meta strip: label left, provenance right — both in flow, so the
   label can no longer sit on top of the copy. Row 2 is the product row.     */

.estate-ad-728x90 {
  width: 728px;
  height: 90px;
  max-width: 100%;
  padding: 7px 14px;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto minmax(0, 1fr);
  column-gap: 16px;
  row-gap: 5px;
}

.estate-ad-728x90 .estate-ad-label {
  grid-column: 1;
  grid-row: 1;
}

.estate-ad-728x90 .estate-ad-provenance {
  grid-column: 2;
  grid-row: 1;
  justify-content: flex-end;
}

.estate-ad-728x90 .estate-ad-link {
  grid-column: 1 / -1;
  grid-row: 2;
  grid-template-columns: 52px minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 13px;
}

.estate-ad-imgwrap-728x90 {
  width: 52px;
  height: 52px;
  padding: 4px;
}

.estate-ad-728x90 .estate-ad-headline {
  font-size: 14px;
  -webkit-line-clamp: 1;
}

.estate-ad-728x90 .estate-ad-body {
  font-size: 11.5px;
  -webkit-line-clamp: 1;
}

.estate-ad-728x90 .estate-ad-ctarow {
  gap: 14px;
  padding-inline-start: 6px;
}

.estate-ad-728x90 .estate-ad-price {
  margin: 0;
  font-size: 16px;
}

/* =====  160x600 skyscraper  ===============================================
   Taller creative (220px), 4-line headline, 7-line body, and the footer sits
   on a hairline at the bottom — the old dead gap is now a divider.          */

.estate-ad-160x600 {
  width: 160px;
  height: 600px;
  max-width: 100%;
  padding: 11px;
  grid-template-rows: auto minmax(0, 1fr) auto;
  row-gap: 10px;
}

.estate-ad-160x600 .estate-ad-link {
  grid-template-rows: auto minmax(0, 1fr) auto;
  row-gap: 10px;
}

.estate-ad-imgwrap-160x600 {
  width: 100%;
  height: 220px;
}

/* short copy centres in the space left over instead of leaving a bottom void */
.estate-ad-160x600 .estate-ad-copy {
  grid-row: 2;
  align-self: center;
  flex: none;
}

.estate-ad-160x600 .estate-ad-headline {
  -webkit-line-clamp: 4;
}

.estate-ad-160x600 .estate-ad-body {
  -webkit-line-clamp: 7;
}

.estate-ad-160x600 .estate-ad-ctarow {
  grid-row: 3;
  flex-direction: column;
  align-items: stretch;
  gap: 9px;
  padding-top: 12px;
  border-top: 1px solid var(--ad-line);
}

.estate-ad-160x600 .estate-ad-price {
  margin: 0;
  font-size: 20px;
}

.estate-ad-160x600 .estate-ad-cta {
  justify-content: center;
  padding: 10px 12px;
}

.estate-ad-160x600 .estate-ad-provenance {
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  white-space: normal;
}

/* =====  320x100 mobile banner  ============================================
   Same meta strip as the leaderboard. Price and CTA stack in a fixed right
   column so the headline always gets its two lines.                         */

.estate-ad-320x100 {
  width: 320px;
  height: 100px;
  max-width: 100%;
  padding: 9px 11px;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto minmax(0, 1fr);
  column-gap: 10px;
  row-gap: 6px;
}

.estate-ad-320x100 .estate-ad-label {
  grid-column: 1;
  grid-row: 1;
}

.estate-ad-320x100 .estate-ad-provenance {
  grid-column: 2;
  grid-row: 1;
  justify-content: flex-end;
}

/* "No tracking" is dropped here for space; Powered by URSY.AD stays */
.estate-ad-320x100 .estate-ad-provenance > span {
  display: none;
}

.estate-ad-320x100 .estate-ad-link {
  grid-column: 1 / -1;
  grid-row: 2;
  grid-template-columns: 48px minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 10px;
}

.estate-ad-imgwrap-320x100 {
  width: 48px;
  height: 48px;
  padding: 4px;
  border-radius: 8px;
}

.estate-ad-320x100 .estate-ad-headline {
  font-size: 13px;
  line-height: 1.26;
}

.estate-ad-320x100 .estate-ad-body {
  display: none;
}

.estate-ad-320x100 .estate-ad-ctarow {
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}

.estate-ad-320x100 .estate-ad-price {
  margin: 0;
  font-size: 14.5px;
}

.estate-ad-320x100 .estate-ad-cta {
  padding: 5px 9px;
  border-radius: 7px;
  font-size: 10.5px;
}

/* =====  anchored phone banner (different markup, no provenance)  ========== */

.estate-ad-anchor {
  --ad-accent: var(--estate-ad-accent, #f2c65c);
  --ad-accent-ink: #1a1405;
  --ad-ink: #14161d;
  --ad-title: #f6f7f9;
  --ad-body: #a4a7b2;
  --ad-meta: #767b8a;
  position: fixed;
  left: 50%;
  bottom: calc(8px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 70;
  display: grid;
  grid-template-rows: auto auto;
  row-gap: 5px;
  width: min(320px, calc(100vw - 20px));
  min-height: 64px;
  box-sizing: border-box;
  overflow: hidden;
  padding: 10px 12px;
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 12px;
  background: var(--ad-ink);
  color: var(--ad-title);
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  box-shadow: 0 -1px 0 rgba(255, 255, 255, .04), 0 10px 30px rgba(10, 11, 15, .45);
}

.estate-ad-anchor .estate-ad-label {
  display: flex;
  margin: 0;
}

.estate-ad-anchor-link {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 10px;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}

/* whole anchored banner is clickable too */
.estate-ad-anchor-link::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

.estate-ad-anchor-link strong {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
  grid-column: 1;
  color: var(--ad-title);
  font-size: 13px;
  font-weight: 700;
  line-height: 1.25;
}

.estate-ad-anchor-link span {
  grid-column: 1;
  color: var(--ad-body);
  font-size: 11.5px;
  font-weight: 400;
}

/* decorative CTA disc — CSS content, so the renderer stays as it is */
.estate-ad-anchor-link::after {
  content: "\2192";
  grid-column: 2;
  grid-row: 1 / span 2;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: var(--ad-accent);
  color: var(--ad-accent-ink);
  font-size: 15px;
  font-weight: 700;
  transition: transform .14s ease;
}

.estate-ad-anchor-link:hover::after {
  transform: translateX(2px);
}

/* =====  dark page (estate convention: [data-theme="dark"] = light card) ====
   On a dark page the advert inverts to a light card so it still reads as an
   advert rather than as editorial. Accent darkens to hold contrast.         */

/* 10 Sep 2026: this rule used to match only [data-theme="dark"], which a visitor sets. ursy.games is dark
   BY DESIGN and says so with body.ueb-dark, so its plates never reached this rule and sat black-on-black —
   visible on the theme's own mid-page plate at 1280 today. The two :has() selectors bring every dark
   property in, which is what makes Lee's rule true everywhere: black card on the light sites, white card
   on ursy.games. */
[data-theme="dark"] .estate-ad,
[data-theme="dark"] .estate-ad-anchor,
html:has(body.ueb-dark) .estate-ad,
html:has(body.ueb-dark) .estate-ad-anchor,
html:has(body.ursy-dark) .estate-ad,
html:has(body.ursy-dark) .estate-ad-anchor {
  /* REVISED 11 September 2026: was #a3700a. On the LIGHT plate that amber is
     the disclosure chip text AND the CTA ground, and both fell short:
       .estate-ad-chip  "Advert"        on white     4.30:1   FAILS
       .estate-ad-cta   "View product"  on the amber 4.03:1   FAILS
     Measured live on ursy.photos, which renders the light plate. Darkening the
     one token lifts BOTH, because one is the ink and the other is its ground:
       chip on white 5.36  |  chip on the #f4f3ef plate 4.83  |  CTA ink 5.02
     #9a6a09 was tried first and clears only the white case, so it is not the
     answer. The dark plate keeps the bright #f2c65c - it is read on near-black
     there and already measures 11.19:1. */
  --ad-accent: #8f6208;
  --ad-accent-ink: #fff7e4;
  --ad-ink: #fff;
  --ad-line: rgba(12, 14, 20, .13);
  --ad-title: #0e1016;
  --ad-body: #4b4f5b;
  --ad-meta: #6b7080;
  --ad-plate: #f4f3ef;
  border-color: rgba(12, 14, 20, .13);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12), 0 12px 30px rgba(0, 0, 0, .3);
}

/* REVISED 11 September 2026. The 10 Sep fix added the two :has() selectors to the block ABOVE so that
   properties which are dark BY DESIGN - ursy.games says so with body.ueb-dark, not data-theme - would
   get the light card. THESE FOUR RULES WERE LEFT BEHIND on [data-theme="dark"] alone, so on ursy.games
   they never fired. Measured live in the footer plate: the price rendered #fff on the #fff card -
   1.00:1, the price of the product INVISIBLE, on the one property Lee singled out for the white card.
   The other three happened to survive on the tokens the block above sets, but they were equally
   unreached and are brought across too. A selector list extended on one rule and not on the rules that
   depend on it is the same partial fix as the ursy.food head blocks. */
[data-theme="dark"] .estate-ad-advertiser,
html:has(body.ueb-dark) .estate-ad-advertiser,
html:has(body.ursy-dark) .estate-ad-advertiser {
  color: #3b3f4b;
}

[data-theme="dark"] .estate-ad-price,
html:has(body.ueb-dark) .estate-ad-price,
html:has(body.ursy-dark) .estate-ad-price {
  color: #0e1016;
}

[data-theme="dark"] .estate-ad-powered,
html:has(body.ueb-dark) .estate-ad-powered,
html:has(body.ursy-dark) .estate-ad-powered {
  color: #5b6070;
  border-color: rgba(12, 14, 20, .22);
}

[data-theme="dark"] .estate-ad-link:hover .estate-ad-cta,
html:has(body.ueb-dark) .estate-ad-link:hover .estate-ad-cta,
html:has(body.ursy-dark) .estate-ad-link:hover .estate-ad-cta {
  background: #8a5d04;
}

/* --- RTL ------------------------------------------------------------------ */

body.is-rtl .estate-ad,
body.is-rtl .estate-ad-anchor {
  direction: rtl;
}

body.is-rtl .estate-ad-728x90 .estate-ad-provenance,
body.is-rtl .estate-ad-320x100 .estate-ad-provenance {
  justify-content: flex-end;
}

/* --- motion -------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .estate-ad-cta,
  .estate-ad-cta i,
  .estate-ad-anchor-link::after {
    transition: none;
  }
}

/* ==========================================================================
   2.4.0, 9 September 2026 — the plate inside the estate footer, and the three
   arrangements.

   Written to finish the 5 September work that was committed and deliberately
   NOT deployed because this stylesheet did not exist yet ("do not deploy until
   it is", commit 97ca678). Two separate jobs live below.

   1. .estate-ad-infoot — the plate sitting ON THE FOOTER'S OWN GROUND. Out in
      the page the plate is a dark slab, which is the whole thing Lee objected
      to. Inside the footer it must read as part of the footer, so every one of
      the plate's own --ad-* tokens is re-pointed at the brand layer's --ueb-*
      tokens. Because .estate-ad declares those tokens on itself, re-declaring
      them here cascades to every child without touching a single child rule.
      The accent bar stays: it is the URSY.AD signature, not decoration.

   2. .estate-ad-style-a / -b / -c — three arrangements of the SAME markup, so a
      reader meeting the estate across twelve sites does not learn to skip one
      fixed shape. No style hides an image the browser has already fetched;
      each simply arranges what is there.
   ========================================================================== */

/* REVISED 10 September 2026, Lee: "the default ad card should have the black box
   unless its on ursy.games that has a dark background then it should be white,
   but 95% of the sites should be black advert card."

   Until now this block did the opposite. It re-pointed every --ad-* token at the
   brand layer's --ueb-* tokens so the plate dissolved into the footer, which made
   the card WHITE on the eleven light properties and dark on ursy.games — exactly
   inverted from what Lee wants. The re-pointing is gone. The plate keeps its own
   dark tokens (declared on .estate-ad itself), so a light site gets the black
   card; the rule below hands ursy.games and any dark theme the white one.

   What stays from the footer work: the plate sits flush in the footer with no
   margin of its own, and it borrows the footer's UI font so the type matches the
   rest of the footer rather than shouting. */
.estate-ad.estate-ad-infoot {
  margin: 0;
  font-family: var(--ueb-ui, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
}

/* The dark properties — ursy.games by design, plus anyone whose visitor has asked
   for a dark theme — take the light card, so the plate never disappears into a
   dark footer. These are the same values as the [data-theme="dark"] .estate-ad
   rule above; they are repeated at .estate-ad-infoot specificity so this wins
   wherever both could apply. */
[data-theme="dark"] .estate-ad.estate-ad-infoot,
html:has(body.ursy-dark) .estate-ad.estate-ad-infoot,
html:has(body.ueb-dark) .estate-ad.estate-ad-infoot {
  /* REVISED 11 September 2026: was #a3700a. On the LIGHT plate that amber is
     the disclosure chip text AND the CTA ground, and both fell short:
       .estate-ad-chip  "Advert"        on white     4.30:1   FAILS
       .estate-ad-cta   "View product"  on the amber 4.03:1   FAILS
     Measured live on ursy.photos, which renders the light plate. Darkening the
     one token lifts BOTH, because one is the ink and the other is its ground:
       chip on white 5.36  |  chip on the #f4f3ef plate 4.83  |  CTA ink 5.02
     #9a6a09 was tried first and clears only the white case, so it is not the
     answer. The dark plate keeps the bright #f2c65c - it is read on near-black
     there and already measures 11.19:1. */
  --ad-accent: #8f6208;
  --ad-accent-ink: #fff7e4;
  --ad-ink: #fff;
  --ad-line: rgba(12, 14, 20, .13);
  --ad-title: #0e1016;
  --ad-body: #4b4f5b;
  --ad-meta: #6b7080;
  --ad-plate: #f4f3ef;
  background: var(--ad-ink);
  color: var(--ad-title);
  border-color: rgba(12, 14, 20, .13);
}

/* The row that carries the plate inside a site's OWN footer, on properties that do
   not run the estate footer (ursy.food). It is the counterpart of .ueb-foot__ad in
   the brand layer: centre the unit, give it air above, and keep it on the footer's
   ground so nothing behind the footer shows through. Lee, 10 Sep 2026: "the advert
   placement needs to be central". */
.estate-ad-footrow {
  display: flex;
  justify-content: center;
  width: 100%;
  padding: clamp(16px, 2.4vw, 26px) 20px clamp(4px, 1vw, 10px);
  box-sizing: border-box;
}
.estate-ad-footrow > .estate-ad { margin: 0; }

/* The in-content placement, added 10 September 2026 so the MPU and the skyscraper are actually served —
   the estate had one slot (the footer), which can only carry a wide band, so two of the four shapes the
   stylesheet defines had never appeared on any page. Centred by default. The skyscraper becomes a proper
   side rail once the column is wide enough to lose 186px without squeezing the text; below that it comes
   back into the flow rather than shrinking the article around it. */
.estate-ad-inline {
  display: flex;
  justify-content: center;
  margin: clamp(22px, 3vw, 34px) 0;
}
.estate-ad-inline > .estate-ad { margin: 0; }

@media (min-width: 1100px) {
  .estate-ad-inline:has(> .estate-ad-160x600) {
    float: right;
    width: 160px;
    margin: 6px 0 20px 26px;
  }
}
/* A float has to be closed off, or the next heading rides up beside the advert. */
.estate-ad-inline::after { content: ""; display: table; clear: both; }

/* -------- arrangement a: thumbnail left. The plate's own rhythm, unchanged. -- */

/* -------- arrangement b: mirrored — thumbnail right, copy leading ----------- */
.estate-ad-style-b.estate-ad-728x90 .estate-ad-link { grid-template-columns: auto minmax(0, 1fr) 52px; }
.estate-ad-style-b.estate-ad-320x100 .estate-ad-link { grid-template-columns: auto minmax(0, 1fr) 48px; }
.estate-ad.estate-ad-style-b .estate-ad-imgwrap { order: 3; }
.estate-ad.estate-ad-style-b .estate-ad-copy { order: 2; }
.estate-ad.estate-ad-style-b .estate-ad-ctarow { order: 1; }
.estate-ad.estate-ad-style-b .estate-ad-label { justify-self: start; }

/* -------- arrangement c: the picture as a flush rail, not an inset chip ------
   Same image, same bytes; it simply runs the full height of the unit hard
   against the edge, which reads as a different unit at a glance. */
.estate-ad-style-c.estate-ad-728x90 .estate-ad-link { grid-template-columns: 108px minmax(0, 1fr) auto; column-gap: 15px; }
.estate-ad-style-c.estate-ad-320x100 .estate-ad-link { grid-template-columns: 72px minmax(0, 1fr) auto; column-gap: 11px; }
.estate-ad.estate-ad-style-c .estate-ad-imgwrap {
  width: auto;
  height: 100%;
  padding: 0;
  border-radius: 8px;
  box-shadow: inset 0 0 0 1px var(--ad-line);
}
.estate-ad.estate-ad-style-c .estate-ad-img { width: 100%; height: 100%; object-fit: cover; }
.estate-ad.estate-ad-style-c .estate-ad-headline { font-weight: 650; }

/* -------- a card with no image must never leave a hole where one would be ----
   ursy.id serves the text card (its CSP allows no remote images), so the
   imgwrap is not printed at all. Without this the copy would sit in the column
   the picture was meant to fill. Scoped to the three new styles so it cannot
   change how the plate behaves anywhere it already works. */
.estate-ad-noimg.estate-ad-style-a .estate-ad-link,
.estate-ad-noimg.estate-ad-style-b .estate-ad-link,
.estate-ad-noimg.estate-ad-style-c .estate-ad-link { grid-template-columns: minmax(0, 1fr) auto; }

/* -------- the phone: one arrangement, because there is no room for three ----- */
@media (max-width: 560px) {
  .estate-ad.estate-ad-infoot { height: auto; }
  .estate-ad-style-b .estate-ad-imgwrap,
  .estate-ad-style-b .estate-ad-copy,
  .estate-ad-style-b .estate-ad-ctarow { order: 0; }
  .estate-ad-style-b.estate-ad-728x90 .estate-ad-link,
  .estate-ad-style-c.estate-ad-728x90 .estate-ad-link { grid-template-columns: 52px minmax(0, 1fr) auto; column-gap: 13px; }
  .estate-ad-style-b.estate-ad-320x100 .estate-ad-link,
  .estate-ad-style-c.estate-ad-320x100 .estate-ad-link { grid-template-columns: 48px minmax(0, 1fr) auto; column-gap: 10px; }
  .estate-ad-style-c .estate-ad-imgwrap { height: 48px; width: 48px; padding: 4px; }

  /* 11 September 2026: the 728px footer unit also renders on phones.
     At 375px its provenance squeezed the label track to 29px: the 61px
     ADVERT chip overlapped it, the advertiser vanished, and the product copy
     had only 35px. Give disclosure, product, and provenance their own rows,
     with price and action below the picture/copy. Fixed-size placements keep
     their declared size; only the already auto-height footer reflows. */
  .estate-ad-infoot.estate-ad-728x90 {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    row-gap: 8px;
  }
  .estate-ad-infoot.estate-ad-728x90 .estate-ad-label {
    grid-column: 1;
    grid-row: 1;
  }
  .estate-ad-infoot.estate-ad-728x90 .estate-ad-link {
    grid-column: 1;
    grid-row: 2;
    grid-template-columns: 52px minmax(0, 1fr);
    row-gap: 8px;
  }
  .estate-ad-infoot.estate-ad-728x90 .estate-ad-ctarow {
    grid-column: 1 / -1;
    grid-row: 2;
    justify-content: space-between;
    padding-inline-start: 0;
  }
  .estate-ad-infoot.estate-ad-728x90 .estate-ad-provenance {
    grid-column: 1;
    grid-row: 3;
    justify-content: space-between;
    flex-wrap: wrap;
  }
  .estate-ad-infoot.estate-ad-728x90.estate-ad-noimg .estate-ad-link {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ==========================================================================
   THE PLATE'S OWN COLOURS MUST SURVIVE THE HOST THEME.

   ADDED 11 September 2026, found on ursy.food the moment its plate was put back
   to the black card. Its theme carries

     .ursy a { color: var(--ursy-link); }

   which is (0,1,1) - one class plus one ELEMENT - and that quietly outranks
   every single-class rule in this file at (0,1,0). So the site's link colour
   won, and three of the plate's own links took it:

     .estate-ad-advertiser   teal #087a8c on the dark plate   3.59:1   FAILS
     .estate-ad-powered      teal #087a8c on the dark plate   3.59:1   FAILS
     .estate-ad-link         teal, where the plate wants its title ink

   The advertiser name is the SPONSOR DISCLOSURE. A paid placement whose
   disclosure cannot be read is not disclosed.

   IT ONLY LOOKED FINE BEFORE BY ACCIDENT. While that property was wrongly
   rendering a WHITE plate, teal on white measured 6.23:1 and passed. The leak
   was always there; the wrong background was hiding it.

   THIS IS NOT AN ursy.food FIX. Any host theme with a `.something a` rule beats
   this file, and twelve properties embed this plate. Raising these three rules
   to (0,2,0) - the .estate-ad ancestor plus the class - puts them above a
   (0,1,1) descendant rule without an !important anywhere, and without touching
   a single declared value: the colours below are the same ones already set
   above, restated at a specificity that holds.

   SIMULATED ON THE LIVE PAGE BEFORE SHIPPING, via CSSOM insertRule: 51 links on
   the page, exactly 3 changed, all three inside the plate, none outside it.
   ========================================================================== */
.estate-ad .estate-ad-advertiser { color: #ced1d9; }
.estate-ad .estate-ad-powered { color: #a2a8b6; }
.estate-ad .estate-ad-link { color: var(--ad-title); }

/* The light plate restates them too, or the rules above would hand a dark-plate
   colour to ursy.games and to any visitor who has asked for a dark theme. Same
   values as the light-plate block earlier in this file. */
[data-theme="dark"] .estate-ad .estate-ad-advertiser,
html:has(body.ursy-dark) .estate-ad .estate-ad-advertiser,
html:has(body.ueb-dark) .estate-ad .estate-ad-advertiser { color: var(--ad-body); }

[data-theme="dark"] .estate-ad .estate-ad-powered,
html:has(body.ursy-dark) .estate-ad .estate-ad-powered,
html:has(body.ueb-dark) .estate-ad .estate-ad-powered { color: var(--ad-meta); }


/* URSY advert placement refinement 2026-09-12.1.
   Automatic placements are horizontal bands. Product selection and links are
   unchanged. Explicit MPU and skyscraper slots keep their own layouts. */
.estate-ad-inline,
.estate-ad-footrow,
.ueb-foot__ad {
  container-type: inline-size;
  container-name: ursy-ad-space;
  min-width: 0;
}
.estate-ad-inline {
  clear: both;
  float: none;
  width: 100%;
  padding-inline: 16px;
  box-sizing: border-box;
  margin-block: 24px;
}
.estate-ad-footrow,
.ueb-foot__ad {
  display: flex;
  justify-content: center;
  padding-block: 20px;
}
.estate-ad.estate-ad-slot-footer,
.estate-ad.estate-ad-slot-incontent {
  margin: 0 auto;
  flex: 0 1 728px;
  box-shadow: 0 2px 4px rgb(0 0 0 / .12), 0 8px 20px rgb(0 0 0 / .13);
}
.estate-ad.estate-ad-728x90 {
  width: 728px;
  max-width: 100%;
  height: 90px;
  grid-template-columns: minmax(0,1fr) auto;
  grid-template-rows: 18px minmax(0,1fr);
  padding: 7px 12px;
  gap: 5px 12px;
}
.estate-ad.estate-ad-728x90 .estate-ad-label {
  grid-area: 1 / 1;
  letter-spacing: .06em;
  white-space: nowrap;
}
.estate-ad.estate-ad-728x90 .estate-ad-provenance {
  grid-area: 1 / 2;
  justify-content: flex-end;
  flex-wrap: nowrap;
}
.estate-ad.estate-ad-728x90 .estate-ad-link {
  grid-area: 2 / 1 / 3 / -1;
  grid-template-columns: 48px minmax(0,1fr) auto;
  grid-template-rows: minmax(0,1fr);
  column-gap: 12px;
  align-items: center;
}
.estate-ad.estate-ad-728x90 .estate-ad-imgwrap {
  grid-area: 1 / 1;
  order: 0;
  width: 48px;
  height: 48px;
  padding: 4px;
}
.estate-ad.estate-ad-728x90 .estate-ad-img {
  object-fit: contain;
}
.estate-ad.estate-ad-728x90 .estate-ad-copy {
  grid-area: 1 / 2;
  order: 0;
}
.estate-ad.estate-ad-728x90 .estate-ad-ctarow {
  grid-area: 1 / 3;
  order: 0;
  padding: 0;
  gap: 12px;
  justify-content: flex-end;
  flex-direction: row;
}
.estate-ad.estate-ad-728x90.estate-ad-noimg .estate-ad-link {
  grid-template-columns: minmax(0,1fr) auto;
}
.estate-ad.estate-ad-728x90.estate-ad-noimg .estate-ad-copy { grid-column: 1; }
.estate-ad.estate-ad-728x90.estate-ad-noimg .estate-ad-ctarow { grid-column: 2; }

/* The local placement width drives the phone card, including a narrow desktop
   column. The media query also covers native theme bands without a wrapper. */
@container ursy-ad-space (max-width: 727px) {
  .estate-ad.estate-ad-728x90 {
    width: 320px;
    flex-basis: 320px;
    height: 100px;
    padding: 8px 10px;
    gap: 5px 6px;
  }
  .estate-ad.estate-ad-728x90 .estate-ad-label { gap: 5px; font-size: 8px; }
  .estate-ad.estate-ad-728x90 .estate-ad-chip { padding: 1px 4px; letter-spacing: .08em; }
  .estate-ad.estate-ad-728x90 .estate-ad-provenance > span { display: none; }
  .estate-ad.estate-ad-728x90 .estate-ad-powered { font-size: 7px; letter-spacing: 0; padding: 1px 4px; }
  .estate-ad.estate-ad-728x90 .estate-ad-link { grid-template-columns: 44px minmax(0,1fr) 88px; gap: 8px; }
  .estate-ad.estate-ad-728x90 .estate-ad-imgwrap { width: 44px; height: 48px; padding: 3px; }
  .estate-ad.estate-ad-728x90 .estate-ad-headline { font-size: 12px; line-height: 1.3; -webkit-line-clamp: 2; }
  .estate-ad.estate-ad-728x90 .estate-ad-body { display: none; }
  .estate-ad.estate-ad-728x90 .estate-ad-ctarow { flex-direction: column; align-items: flex-end; gap: 4px; }
  .estate-ad.estate-ad-728x90 .estate-ad-price { font-size: 14px; }
  .estate-ad.estate-ad-728x90 .estate-ad-cta { font-size: 10px; padding: 6px 7px; gap: 3px; }
}
@media (max-width: 727px) {
  .estate-ad.estate-ad-728x90 {
    width: 320px;
    flex-basis: 320px;
    height: 100px;
    padding: 8px 10px;
    gap: 5px 6px;
  }
  .estate-ad.estate-ad-728x90 .estate-ad-label { gap: 5px; font-size: 8px; }
  .estate-ad.estate-ad-728x90 .estate-ad-chip { padding: 1px 4px; letter-spacing: .08em; }
  .estate-ad.estate-ad-728x90 .estate-ad-provenance > span { display: none; }
  .estate-ad.estate-ad-728x90 .estate-ad-powered { font-size: 7px; letter-spacing: 0; padding: 1px 4px; }
  .estate-ad.estate-ad-728x90 .estate-ad-link { grid-template-columns: 44px minmax(0,1fr) 88px; gap: 8px; }
  .estate-ad.estate-ad-728x90 .estate-ad-imgwrap { width: 44px; height: 48px; padding: 3px; }
  .estate-ad.estate-ad-728x90 .estate-ad-headline { font-size: 12px; line-height: 1.3; -webkit-line-clamp: 2; }
  .estate-ad.estate-ad-728x90 .estate-ad-body { display: none; }
  .estate-ad.estate-ad-728x90 .estate-ad-ctarow { flex-direction: column; align-items: flex-end; gap: 4px; }
  .estate-ad.estate-ad-728x90 .estate-ad-price { font-size: 14px; }
  .estate-ad.estate-ad-728x90 .estate-ad-cta { font-size: 10px; padding: 6px 7px; gap: 3px; }
}

/* Helper 222: a holding footer already supplies its own page gutter. The
   nested advert row must not remove a second 40px from the phone placement. */
.ue-footer .estate-ad-footrow { padding-inline: 0; }
.ucs-foot__inner > .estate-ad.estate-ad-slot-footer { margin: 24px auto 20px; }

.uth2-body > .estate-ad-inline { margin-block: 40px; padding-inline: 0; }

/* The UTH band overrides older theme-specific phone stacking. */
html .uth2-body .estate-ad.estate-ad-728x90 {
  width: 728px;
  max-width: 100%;
  height: 90px;
  grid-template-columns: minmax(0,1fr) auto;
  grid-template-rows: 18px minmax(0,1fr);
  padding: 7px 12px;
  gap: 5px 12px;
}
html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-label {
  grid-area: 1 / 1;
  letter-spacing: .06em;
  white-space: nowrap;
}
html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-provenance {
  grid-area: 1 / 2;
  justify-content: flex-end;
  flex-wrap: nowrap;
}
html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-link {
  grid-area: 2 / 1 / 3 / -1;
  grid-template-columns: 48px minmax(0,1fr) auto;
  grid-template-rows: minmax(0,1fr);
  column-gap: 12px;
  align-items: center;
}
html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-imgwrap {
  grid-area: 1 / 1;
  order: 0;
  width: 48px;
  height: 48px;
  padding: 4px;
}
html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-img {
  object-fit: contain;
}
html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-copy {
  grid-area: 1 / 2;
  order: 0;
}
html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-ctarow {
  grid-area: 1 / 3;
  order: 0;
  padding: 0;
  gap: 12px;
  justify-content: flex-end;
  flex-direction: row;
}
html .uth2-body .estate-ad.estate-ad-728x90.estate-ad-noimg .estate-ad-link {
  grid-template-columns: minmax(0,1fr) auto;
}
html .uth2-body .estate-ad.estate-ad-728x90.estate-ad-noimg .estate-ad-copy { grid-column: 1; }
html .uth2-body .estate-ad.estate-ad-728x90.estate-ad-noimg .estate-ad-ctarow { grid-column: 2; }

/* The local placement width drives the phone card, including a narrow desktop
   column. The media query also covers native theme bands without a wrapper. */
@container ursy-ad-space (max-width: 727px) {
  html .uth2-body .estate-ad.estate-ad-728x90 {
    width: 320px;
    flex-basis: 320px;
    height: 100px;
    padding: 8px 10px;
    gap: 5px 6px;
  }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-label { gap: 5px; font-size: 8px; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-chip { padding: 1px 4px; letter-spacing: .08em; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-provenance > span { display: none; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-powered { font-size: 7px; letter-spacing: 0; padding: 1px 4px; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-link { grid-template-columns: 44px minmax(0,1fr) 88px; gap: 8px; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-imgwrap { width: 44px; height: 48px; padding: 3px; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-headline { font-size: 12px; line-height: 1.3; -webkit-line-clamp: 2; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-body { display: none; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-ctarow { flex-direction: column; align-items: flex-end; gap: 4px; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-price { font-size: 14px; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-cta { font-size: 10px; padding: 6px 7px; gap: 3px; }
}
@media (max-width: 727px) {
  html .uth2-body .estate-ad.estate-ad-728x90 {
    width: 320px;
    flex-basis: 320px;
    height: 100px;
    padding: 8px 10px;
    gap: 5px 6px;
  }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-label { gap: 5px; font-size: 8px; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-chip { padding: 1px 4px; letter-spacing: .08em; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-provenance > span { display: none; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-powered { font-size: 7px; letter-spacing: 0; padding: 1px 4px; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-link { grid-template-columns: 44px minmax(0,1fr) 88px; gap: 8px; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-imgwrap { width: 44px; height: 48px; padding: 3px; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-headline { font-size: 12px; line-height: 1.3; -webkit-line-clamp: 2; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-body { display: none; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-ctarow { flex-direction: column; align-items: flex-end; gap: 4px; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-price { font-size: 14px; }
  html .uth2-body .estate-ad.estate-ad-728x90 .estate-ad-cta { font-size: 10px; padding: 6px 7px; gap: 3px; }
}
