/* ===========================================================================
   THE GOOD GUIDE  —  /the-good-guide
   Standalone stylesheet. Loaded only by the-good-guide.php.

   Palette is lifted from the AMI Suites pocket guide and from style.css, so
   nothing here introduces a new brand colour:
     #033542  deep teal      (already the site's .shrink header colour)
     #be7f1c  mustard        (already the site's link/hover colour)
     #d09b2c  light mustard
     #5a8590  blue-grey
     #c4622d  terracotta
   Type is Recoleta (display) + Untitled Sans (body), both already self-hosted
   in css/font/ and registered by style.css. Two extra weights are registered
   below because style.css only declares four of the eleven available faces.

   PHASE 1 (map spine rebuild): the hero is a neighbourhood MAP, built as a
   layered composite — a plain code-drawn radial placeholder for now. See the
   "map" section below and the redesign plan. Nothing bakes a venue or label
   into an image; rings, pins, captions and the centre mark are all code.
   ======================================================================== */

@font-face {
    font-family: recoleta-semibold;
    src: url('font/Recoleta-SemiBold.woff') format('woff');
    font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
    font-family: untitled-regular;
    src: url('font/untitled-sans-regular.woff') format('woff');
    font-weight: 400; font-style: normal; font-display: swap;
}

:root {
    --gg-teal:      #033542;
    --gg-teal-soft: #0a4a5a;
    --gg-mustard:   #be7f1c;
    --gg-mustard-l: #d09b2c;
    --gg-grey:      #5a8590;
    --gg-sage:      #c3d1d0;
    --gg-terra:     #c4622d;
    --gg-cream:     #f8f4ea;
    --gg-cream-d:   #efe8d8;
    --gg-ink:       #22282a;
    --gg-ink-soft:  #5c6668;
    --gg-radius:    14px;
    --gg-arch:      999px 999px var(--gg-radius) var(--gg-radius);
}

/* ---------------------------------------------------------------- shell -- */

.gg-page {
    background: var(--gg-cream);
    color: var(--gg-ink);
    font-family: untitled-regular, untitled, sans-serif;
    /* Type dialled down to sit closer to the rest of the site (owner feedback
       2026-08-26: the page read a touch larger + more spread than other pages).
       Base size + line-height pulled in; the widest display tracking reduced
       below; map-internal labels left alone (they are tuned to the plate art). */
    font-size: 15px;
    line-height: 1.55;
    overflow-x: hidden;
}
.gg-page ::selection { background: var(--gg-mustard); color: #fff; }

.gg-wrap {
    width: 100%;
    max-width: 1240px;
    margin: 0 auto;
    padding: 0 28px;
}

.gg-page h1, .gg-page h2, .gg-page h3 {
    font-family: recoleta-semibold, recoleta-regular, recoleta, serif;
    font-weight: 400;
    letter-spacing: -0.01em;
    margin: 0;
}

/* ------------------------------------------------------- forced header -- */
/* This page's hero is cream. The sitewide header is transparent with white
   text (legible only over the dark fullPage heroes every other page has), so
   here it would vanish. Force the solid teal (scrolled) treatment from the
   top. Page-scoped: this stylesheet loads nowhere else. js/good-guide.js also
   adds .shrink/.shrink-m for the compact small-logo state; this CSS guarantees
   legibility even before/without JS. */
#header, #header-m { background-color: var(--gg-teal) !important; }
#header.shrink, #header-m.shrink-m { box-shadow: 0 2px 14px rgba(3,53,66,.18); }

/* The sitewide promo toast is suppressed on the guide (redesign plan §5): it
   overlapped the map's bottom-right chrome. The only fixed bottom-right
   element left is the WhatsApp float. */
.toast { display: none !important; }

/* ------------------------------------------------------------ hero / map -- */
/* Cream field, matching the pocket-guide look and the redesign reference. */
.gg-hero {
    position: relative;
    background: var(--gg-cream);
    color: var(--gg-ink);
    padding: 132px 0 26px;
}
.gg-hero__inner {
    display: grid;
    grid-template-columns: minmax(280px, 0.86fr) minmax(0, 1.14fr);
    gap: 48px;
    align-items: center;
}
.gg-hero__eyebrow {
    font: 12px/1 untitled-bold, untitled, sans-serif;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--gg-mustard);
    margin-bottom: 24px;
}
.gg-hero__title { color: var(--gg-teal); margin-bottom: 22px; }
/* Two visible lines rather than one keyword-stuffed string: the display line
   carries the brand, the second carries the search phrase. Both are real
   on-page text inside the single h1. */
.gg-hero__title-l1 {
    display: block;
    font-size: clamp(40px, 5.2vw, 76px);
    line-height: 0.98;
}
.gg-hero__title-l2 {
    display: block;
    font-family: recoleta, serif;
    font-size: clamp(16px, 1.8vw, 24px);
    line-height: 1.2;
    color: var(--gg-grey);
    margin-top: 14px;
}
.gg-hero__lede {
    font-size: 16px;
    line-height: 1.5;
    color: var(--gg-ink-soft);
    max-width: 30em;
    /* Air above the paragraph, separating it from the "to Mont Kiara & Kuala
       Lumpur" subheader. Lives here, not on .gg-hero__title's margin-bottom:
       `.gg-page h1 { margin: 0 }` (higher specificity) would override that. */
    margin-top: 22px;
    margin-bottom: 30px;
}
.gg-hero__actions { display: flex; flex-wrap: wrap; gap: 14px; }

/* ---- the map itself -------------------------------------------------- */
/* The stage is the coordinate box. Everything positioned inside is placed in
   PERCENT of this box, so one set of coordinates works on the wide desktop
   stage and the tall mobile stage alike — the ellipse reshapes with the box.
   container-type lets pins/labels/arch scale with the stage (cqmin), with px
   fallbacks first for browsers without container units. */
.gg-hero__map { position: relative; }
.gg-map { position: relative; width: 100%; }
.gg-map__stage {
    position: relative;
    width: 100%;
    aspect-ratio: 5 / 4.4;
    container-type: size;
    container-name: ggmap;
}

/* Phase 2: illustrated atmospheric backdrop plate. The WebP is the TOP
   background layer; the cream radial gradient sits UNDER it as a fallback, so
   until the plate art is supplied (img/guide/ empty) the map still reads on a
   soft cream field. The art is decorative only (.gg-map is aria-hidden here) —
   every ring, ring word, pin, label and the centre mark is drawn in code ON TOP
   of this, so the illustration never carries meaning. Desktop plate here; the
   portrait mobile plate is swapped in in the ≤1024px block. */
.gg-map__plate {
    position: absolute; inset: 0;
    border-radius: 20px;
    /* JPG background first (works everywhere); the image-set line below overrides
       it with WebP where supported. A browser that does not understand image-set
       ignores that declaration and keeps the JPG. Cream radial stays the last-
       resort fallback if no plate loads at all. */
    background:
        url('../img/guide/map-backdrop-desktop.jpg') center / cover no-repeat,
        radial-gradient(125% 120% at 50% 56%, #fcf9f2 0%, #f3edde 52%, #e8dfd0 100%);
    background:
        image-set(url('../img/guide/map-backdrop-desktop.webp') type('image/webp'),
                  url('../img/guide/map-backdrop-desktop.jpg') type('image/jpeg')) center / cover no-repeat,
        radial-gradient(125% 120% at 50% 56%, #fcf9f2 0%, #f3edde 52%, #e8dfd0 100%);
    box-shadow: inset 0 0 0 1px rgba(3,53,66,.07);
    overflow: hidden;
}
/* Faint vertical guide from the top down to the centre, like the reference. */
.gg-map__plate::before {
    content: "";
    position: absolute;
    left: 50%; top: 6%; height: 50%;
    border-left: 1px dashed rgba(3,53,66,.14);
}

.gg-map__rings { position: absolute; inset: 0; overflow: visible; }
/* Cream halo drawn UNDER each coloured ring (same ellipse, wider soft stroke)
   so the thin ring line keeps its contrast where the illustration runs darker
   (greenery, skyline). Near-invisible over the cream field, a clean separator
   over the art. */
.gg-ring-halo { fill: none; stroke: rgba(248,244,234,.72); stroke-width: 3.6; }
.gg-ring { fill: none; stroke-width: 1.4; }
.gg-ring--1 { stroke: rgba(196,98,45,.6); }    /* terracotta, inner  */
.gg-ring--2 { stroke: rgba(190,127,28,.6); }   /* mustard, mid       */
.gg-ring--3 { stroke: rgba(3,53,66,.36); }     /* teal, outer        */

/* Ring captions, as real text, sitting on the top of each ring arc. A cream
   chip lets them break the ring line the way the reference does. */
.gg-ring-cap {
    position: absolute;
    transform: translate(-50%, -50%);
    z-index: 3;
    font-family: recoleta-semibold, recoleta, serif;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    white-space: nowrap;
    background: var(--gg-cream);
    padding: 2px 9px;
    border-radius: 999px;
    box-shadow: 0 1px 5px rgba(3,53,66,.1);
    font-size: 11px;                       /* fallback */
    font-size: clamp(9px, 2cqmin, 12.5px); /* scales with stage */
}
.gg-ring-cap--1 { color: var(--gg-terra); }
.gg-ring-cap--2 { color: var(--gg-mustard); }
.gg-ring-cap--3 { color: var(--gg-mustard); }

/* AMI centre mark — the real AMI arch logo (teal) + a "you are here" line.
   The logo PNG already carries the arch monogram + AMI SUITES wordmark, so there
   is no code-drawn arch block any more: smaller, sleeker, and unmistakably the
   brand. Centred on (cx, cy). */
.gg-map__center {
    position: absolute;
    transform: translate(-50%, -50%);
    z-index: 4;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;                              /* fallback */
    gap: 1.6cqmin;
}
/* Soft cream backing so the mark lifts cleanly off a busy illustration.
   Invisible over the plain cream fallback; a gentle halo over the art. */
.gg-map__center::before {
    content: "";
    position: absolute;
    left: 50%; top: 44%;
    width: 250%; height: 260%;
    transform: translate(-50%, -50%);
    background: radial-gradient(closest-side, rgba(248,244,234,.9), rgba(248,244,234,0) 72%);
    z-index: -1;
    pointer-events: none;
}
.gg-map__logo {
    display: block;
    width: 78px;                           /* fallback */
    width: clamp(58px, 15cqmin, 100px);    /* scales with stage */
    height: auto;
}
.gg-map__here {
    font-family: recoleta, serif;
    font-style: italic;
    color: var(--gg-mustard);
    letter-spacing: 0.01em;
    line-height: 1;
    font-size: 12px;                       /* fallback */
    font-size: clamp(9px, 2cqmin, 13px);
}

/* Pins. Real <button>s, absolutely placed by the PHP positioning function. */
.gg-pin {
    position: absolute;
    transform: translate(-50%, -50%);
    z-index: 5;
    appearance: none;
    background: none;
    border: 0;
    padding: 0;
    margin: 0;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    line-height: 1;
    /* Fade when a filter dims/undims the pin, so the map settles into the new
       state over roughly the same window as the card Flip (~0.5s) rather than
       snapping. During the entrance GSAP suspends this transition (inline) so it
       does not fight the fade-in, then restores it. */
    transition: opacity .42s ease;
}
.gg-pin__dot {
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--gg-teal);
    color: #fff;
    border: 2px solid var(--gg-cream);
    /* Cream halo ring separates the dot from darker art; it is invisible over
       the cream fallback (cream-on-cream) and only reads over the illustration. */
    box-shadow: 0 0 0 2.5px rgba(248,244,234,.5), 0 3px 10px rgba(3,53,66,.28);
    font-family: untitled-bold, untitled, sans-serif;
    letter-spacing: 0.02em;
    /* Base timing tuned to the card Flip so a filter's pin pop/dim reads in step
       with the cards reflowing. Hover / pin<->card link override this to stay
       snappy (below). */
    transition: transform .4s cubic-bezier(.2,.7,.3,1), background-color .38s ease, box-shadow .38s ease;
    width: 30px; height: 30px;             /* fallback */
    width: clamp(24px, 5.2cqmin, 34px);
    height: clamp(24px, 5.2cqmin, 34px);
    font-size: 12px;                       /* fallback */
    font-size: clamp(11px, 2.1cqmin, 14px);
}
.gg-pin__label {
    /* Absolutely positioned BELOW the dot rather than sitting in the button's
       flex column. In-flow (even while visibility:hidden) it took vertical
       space, so the button's centre — the point placed on the ring — fell
       between the dot and the label and pushed every dot ~2% ABOVE its true ring
       coordinate (top pins read outside the ring, bottom pins inside). Out of
       flow, the button is just the dot, so the dot centres exactly on its ring
       point. The 6px margin replaces the old flex `gap`. */
    position: absolute;
    top: 100%;
    left: 50%;
    margin-top: 6px;
    font-family: recoleta-semibold, recoleta, serif;
    color: var(--gg-teal);
    background: var(--gg-cream);
    padding: 3px 9px;
    border-radius: 8px;
    /* Long venue names wrap to two lines instead of forcing one very wide line,
       so an edge pin's label is less likely to run off the map. Short names
       stay on one line (they fall under the cap). */
    text-align: center;
    line-height: 1.2;
    max-width: 150px;       /* fallback */
    max-width: 30cqmin;     /* scales with the stage */
    box-shadow: 0 2px 9px rgba(3,53,66,.14);
    opacity: 0;
    visibility: hidden;
    transform: translate(-50%, -3px);
    transition: opacity .2s ease, transform .2s ease;
    pointer-events: none;
    font-size: 13px;                       /* fallback */
    font-size: clamp(11px, 2.3cqmin, 14px);
}

/* Raise the pin the visitor is engaging with above its neighbours. */
.gg-pin:hover, .gg-pin:focus-visible, .gg-pin.is-match, .gg-pin.is-linked { z-index: 8; }

/* Direct interaction (hover, keyboard focus, pin<->card link) stays snappy; only
   the filter-driven state change borrows the slower Flip-matched timing above. */
.gg-pin:hover .gg-pin__dot,
.gg-pin:focus-visible .gg-pin__dot,
.gg-pin.is-linked .gg-pin__dot { transition-duration: .2s; }

/* Hover / keyboard focus: enlarge + reveal the name. */
.gg-pin:hover .gg-pin__dot,
.gg-pin:focus-visible .gg-pin__dot { transform: scale(1.16); background: var(--gg-mustard); }
.gg-pin:hover .gg-pin__label,
.gg-pin:focus-visible .gg-pin__label { opacity: 1; visibility: visible; transform: translate(-50%, 0); }
.gg-pin:focus-visible .gg-pin__dot { outline: 2px solid var(--gg-mustard); outline-offset: 2px; }

/* Category active: matching pins enlarge + keep their label; non-matching fade.
   Default ("Everything") clears both, so the map is small numbered dots. */
.gg-pin.is-match .gg-pin__dot {
    transform: scale(1.14);
    background: var(--gg-mustard);
    box-shadow: 0 4px 14px rgba(190,127,28,.42);
}
.gg-pin.is-match .gg-pin__label { opacity: 1; visibility: visible; transform: translate(-50%, 0); }
.gg-pin.is-dim { opacity: 0.32; }
.gg-pin.is-dim .gg-pin__dot { background: var(--gg-grey); box-shadow: none; }

/* Pin <-> card link (hover/tap a pin highlights its card and vice versa). */
.gg-pin.is-linked .gg-pin__dot {
    transform: scale(1.28);
    background: var(--gg-mustard);
    box-shadow: 0 0 0 4px rgba(190,127,28,.28), 0 5px 16px rgba(3,53,66,.3);
}
.gg-pin.is-linked .gg-pin__label { opacity: 1; visibility: visible; transform: translate(-50%, 0); }

/* --------------------------------------------------------------- buttons -- */

.gg-btn {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 15px 30px;
    border: 1px solid transparent;
    border-radius: 999px;
    font: 12px/1 untitled-bold, untitled, sans-serif;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
    transition: background-color .25s ease, color .25s ease, border-color .25s ease, transform .25s ease;
}
.gg-btn:hover, .gg-btn:focus { text-decoration: none; transform: translateY(-2px); }
.gg-btn--solid  { background: var(--gg-mustard); color: #fff; }
.gg-btn--solid:hover, .gg-btn--solid:focus  { background: var(--gg-mustard-l); color: #fff; }
.gg-btn--ink    { background: var(--gg-teal); color: #fff; }
.gg-btn--ink:hover, .gg-btn--ink:focus { background: var(--gg-teal-soft); color: #fff; }
/* Outlined dark variant for the cream hero (the old white --ghost vanished on
   cream). */
.gg-btn--ghost-ink { border-color: rgba(3,53,66,.28); color: var(--gg-teal); }
.gg-btn--ghost-ink:hover, .gg-btn--ghost-ink:focus { background: var(--gg-teal); border-color: var(--gg-teal); color: #fff; }
/* Outlined variant for light card backgrounds. */
.gg-btn--outline { border-color: rgba(3,53,66,.3); color: var(--gg-teal); }
.gg-btn--outline:hover, .gg-btn--outline:focus { background: var(--gg-teal); border-color: var(--gg-teal); color: #fff; }
.gg-btn--wa .wa-cta-icon { width: 16px; height: 16px; flex: 0 0 auto; }

/* Inline links in body copy. */
.gg-inline {
    color: var(--gg-mustard);
    text-decoration: none;
    border-bottom: 1px solid rgba(190,127,28,.4);
    transition: color .2s ease, border-color .2s ease;
}
.gg-inline:hover, .gg-inline:focus { color: var(--gg-teal); border-color: var(--gg-teal); text-decoration: none; }

/* ---------------------------------------------------------------- intro -- */

.gg-intro { padding: 70px 0 8px; text-align: center; }
.gg-intro__title {
    font-size: clamp(26px, 3vw, 39px);
    line-height: 1.14;
    color: var(--gg-teal);
    /* Owner feedback 2026-08-26: needed clear air between this title and the
       paragraph under it. */
    margin-bottom: 30px;
}
.gg-intro__body {
    font-size: 16px;
    color: var(--gg-ink-soft);
    max-width: 34em;
    margin: 0 auto;
}

/* -------------------------------------------------------------- filters -- */

.gg-filters { padding: 46px 0 10px; }
/* The filter's primary home is directly under the map (inside the hero), so it
   controls the map first and the cards second. Hug the map: tighter top gap,
   no base bottom padding (the hero supplies that). */
.gg-filters--hero { padding: 0; margin-top: 42px; }
.gg-filters__label {
    font: 12px/1 untitled-bold, untitled, sans-serif;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--gg-grey);
    text-align: center;
    margin-bottom: 20px;
}
.gg-chips {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 10px;
}
.gg-chip {
    appearance: none;
    background: transparent;
    border: 1px solid rgba(3,53,66,.22);
    color: var(--gg-teal);
    border-radius: 999px;
    padding: 11px 22px;
    font: 12px/1 untitled-bold, untitled, sans-serif;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    cursor: pointer;
    white-space: nowrap;
    transition: background-color .22s ease, color .22s ease, border-color .22s ease;
}
.gg-chip:hover { border-color: var(--gg-mustard); color: var(--gg-mustard); }
.gg-chip[aria-pressed="true"] {
    background: var(--gg-teal);
    border-color: var(--gg-teal);
    color: #fff;
}
.gg-chip:focus-visible { outline: 2px solid var(--gg-mustard); outline-offset: 3px; }

/* AMI Picks — the cross-zone curation chip. Given a gold identity so it reads as
   AMI's own shortlist, distinct from the teal mood chips. Filters on the 'pick'
   token via the same JS path (data-cat="pick"). */
.gg-chip--pick {
    border-color: rgba(190,127,28,.5);
    color: var(--gg-mustard);
}
.gg-chip--pick:hover { border-color: var(--gg-mustard); color: var(--gg-mustard-l); }
.gg-chip--pick[aria-pressed="true"] {
    background: var(--gg-mustard);
    border-color: var(--gg-mustard);
    color: #fff;
}
.gg-chip__star { margin-right: 6px; font-size: 0.92em; line-height: 0; vertical-align: -1px; }

/* ---------------------------------------------------------------- bands -- */

/* scroll-margin keeps the "Explore the neighbourhood" jump (and any pin->card
   jump) clear of the fixed header, which would otherwise swallow the heading. */
.gg-band {
    padding: 62px 0 10px;
    scroll-margin-top: 108px;
}
.gg-band__head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 30px;
    margin-bottom: 30px;
}
.gg-band__title {
    font-size: clamp(24px, 2.9vw, 37px);
    line-height: 1.1;
    color: var(--gg-teal);
    position: relative;
    padding-left: 0.72em;
}
/* The real AMI arch monogram (cropped from the logo) tucked against each section
   title. Rendered as a mask filled with the heading's own colour (currentColor),
   so it is teal on the cream sections and white on the teal events section with a
   single asset. Sized in em so it scales with the heading; 0.601 w/h keeps the
   monogram's aspect. */
.gg-band__title::before {
    content: "";
    position: absolute;
    left: 0; top: 0.1em;
    width: 0.44em; height: 0.73em;
    background-color: currentColor;
    -webkit-mask: url('../img/guide/ami-arch-teal.png') no-repeat center / contain;
    mask: url('../img/guide/ami-arch-teal.png') no-repeat center / contain;
}
.gg-band__sub {
    color: var(--gg-ink-soft);
    max-width: 34em;
    margin-top: 10px;
    padding-left: 0.9em;
}

/* ---------------------------------------------------------------- cards -- */

.gg-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(286px, 1fr));
    gap: 26px;
}

.gg-card {
    display: flex;
    flex-direction: column;
    background: #fff;
    border-radius: var(--gg-radius);
    overflow: hidden;
    box-shadow: 0 1px 2px rgba(3,53,66,.06), 0 10px 26px rgba(3,53,66,.05);
    transition: transform .3s cubic-bezier(.2,.7,.3,1), box-shadow .3s ease;
}
.gg-card:hover {
    transform: translateY(-6px);
    box-shadow: 0 2px 4px rgba(3,53,66,.07), 0 20px 42px rgba(3,53,66,.11);
}
/* Highlighted when its map pin is hovered/tapped (pin <-> card link). */
.gg-card.is-linked {
    transform: translateY(-4px);
    box-shadow: 0 0 0 2px var(--gg-mustard), 0 20px 42px rgba(3,53,66,.16);
}

/* Arch-topped media, matching the map arch and the pocket-guide language. */
.gg-card__media {
    position: relative;
    aspect-ratio: 16 / 12;
    overflow: hidden;
    background: var(--gg-sage);
    border-radius: 999px 999px 0 0;
    margin: 10px 10px 0;
}
/* <picture> wraps the photo (WebP source + JPG fallback). It is inline by
   default, which would collapse the img's height:100%, so make it fill the
   arch media box like the img did before. */
.gg-card__media picture { display: block; width: 100%; height: 100%; }
/* :not(.gg-card__logo) so the photo cover-fit rules never grab the optional logo
   overlay img (which needs contain + its own size, below). */
.gg-card__media img:not(.gg-card__logo) {
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
    transition: transform .5s cubic-bezier(.2,.7,.3,1);
}
.gg-card:hover .gg-card__media img:not(.gg-card__logo) { transform: scale(1.045); }

/* Optional venue wordmark laid over the photo (e.g. the cream ALLO logo). The
   --branded scrim (a soft teal gradient, darker top + bottom) plus a drop-shadow
   keep a light logo legible over any photo without muddying the image. */
.gg-card__media--branded::after {
    content: "";
    position: absolute; inset: 0;
    background: linear-gradient(180deg, rgba(3,53,66,.30) 0%, rgba(3,53,66,.05) 46%, rgba(3,53,66,.48) 100%);
    z-index: 1;
    pointer-events: none;
}
.gg-card__logo {
    position: absolute;
    left: 50%; top: 52%;
    transform: translate(-50%, -50%);
    width: 62%;
    max-width: 210px;
    height: auto;
    object-fit: contain;
    z-index: 2;
    pointer-events: none;
    filter: drop-shadow(0 2px 9px rgba(3,53,66,.6));
}

/* Branded placeholder, used until marketing supplies photography.
   Colour rotates so a wall of these still reads as a designed grid. */
.gg-ph {
    position: absolute; inset: 0;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background: var(--gg-sage);
    overflow: hidden;
}
.gg-ph::before {
    content: "";
    width: 58%;
    height: 82%;
    border-radius: 999px 999px 0 0;
    background: rgba(255,255,255,.34);
}
.gg-ph__name {
    position: absolute;
    left: 0; right: 0; bottom: 16px;
    padding: 0 18px;
    text-align: center;
    font-family: recoleta-semibold, recoleta, serif;
    font-size: 17px;
    line-height: 1.2;
    color: var(--gg-teal);
}
.gg-card:nth-child(4n+2) .gg-ph { background: var(--gg-mustard-l); }
.gg-card:nth-child(4n+3) .gg-ph { background: var(--gg-grey); }
.gg-card:nth-child(4n+4) .gg-ph { background: var(--gg-terra); }
.gg-card:nth-child(4n+2) .gg-ph__name,
.gg-card:nth-child(4n+3) .gg-ph__name,
.gg-card:nth-child(4n+4) .gg-ph__name { color: #fff; }

/* Numbered badge, straight from the pocket guide's panel numbering. Matches
   the venue's map pin number. */
.gg-card__num {
    position: absolute;
    top: 14px; left: 50%;
    transform: translateX(-50%);
    z-index: 3;                 /* above the optional logo + scrim */
    width: 34px; height: 34px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--gg-teal);
    color: #fff;
    border: 2px solid var(--gg-cream);
    font: 12px/1 untitled-bold, untitled, sans-serif;
    letter-spacing: 0.04em;
}

.gg-card__body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    padding: 18px 22px 22px;
    text-align: center;
}
.gg-card__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin-bottom: 12px;
}
.gg-pill {
    display: inline-block;
    padding: 5px 11px;
    border-radius: 999px;
    font: 10px/1.35 untitled-bold, untitled, sans-serif;
    letter-spacing: 0.13em;
    text-transform: uppercase;
}
.gg-pill--area   { background: var(--gg-cream-d); color: var(--gg-ink-soft); }
.gg-pill--travel { background: rgba(190,127,28,.13); color: var(--gg-mustard); }
/* Conceptual distance zone (Walkable / Short hop / Worth the ride), shown on the
   second pill only when a card has no verified travel time. Teal-tinted so it
   echoes the map/brand and reads distinct from the neutral area pill and the
   mustard travel pill. */
.gg-pill--zone   { background: rgba(3,53,66,.08); color: var(--gg-teal); }

.gg-card__name {
    font-size: 21px;
    line-height: 1.15;
    color: var(--gg-teal);
    margin-bottom: 9px;
}
.gg-card__blurb {
    font-size: 14px;
    line-height: 1.5;
    color: var(--gg-ink-soft);
    margin-bottom: 14px;
}
.gg-card__for {
    font-size: 13px;
    color: var(--gg-ink-soft);
    margin-bottom: 12px;
}
.gg-card__for strong {
    font-family: untitled-bold, untitled, sans-serif;
    color: var(--gg-ink);
    font-weight: 400;
}

.gg-card__tip {
    display: flex;
    gap: 9px;
    text-align: left;
    font-size: 13px;
    line-height: 1.5;
    color: var(--gg-ink-soft);
    background: var(--gg-cream);
    border-left: 2px solid var(--gg-mustard);
    padding: 11px 13px;
    border-radius: 0 8px 8px 0;
    margin-bottom: 14px;
}
.gg-card__tip b {
    font-family: untitled-bold, untitled, sans-serif;
    font-weight: 400;
    color: var(--gg-mustard);
    white-space: nowrap;
}

.gg-card__link {
    margin-top: auto;
    align-self: center;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font: 11px/1 untitled-bold, untitled, sans-serif;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--gg-mustard);
    text-decoration: none;
}
.gg-card__link:hover, .gg-card__link:focus { color: var(--gg-teal); text-decoration: none; }
.gg-card__link svg { transition: transform .25s ease; }
.gg-card__link:hover svg { transform: translateX(4px); }

/* ---------------------------------------------------------------------------
   Cross-card row alignment (owner feedback 2026-08-26). Every card in a grid
   row shares seven row tracks — media, meta, name, blurb, good-for, tip, link —
   so those sections line up horizontally however long each card's copy runs. A
   card that lacks a section (no tip, no link) leaves that track empty and the
   sections it DOES have still align with its neighbours.

   Only the SUBGRID gutters are zeroed (row-gap on the card + body); the parent
   .gg-grid keeps its `gap`, which still spaces cards apart AND separates the
   rows/bands — so there is no fight with the responsive `gap` in the media
   queries. Internal section spacing is the existing per-section margins.

   Progressive enhancement: browsers without subgrid keep the flex card above
   (sections stack, just not cross-aligned). On the 1-column mobile grid each
   card is its own row, so tracks size to that card and nothing stretches. */
@supports (grid-template-rows: subgrid) {
    .gg-card {
        grid-row: span 7;
        display: grid;
        grid-template-rows: subgrid;
        row-gap: 0;
    }
    .gg-card__media { grid-row: 1; }
    .gg-card__body {
        grid-row: 2 / span 6;
        display: grid;
        grid-template-rows: subgrid;
        row-gap: 0;
    }
    .gg-card__meta  { grid-row: 1; }
    .gg-card__name  { grid-row: 2; }
    .gg-card__blurb { grid-row: 3; }
    .gg-card__for   { grid-row: 4; }
    .gg-card__tip   { grid-row: 5; align-self: start; }   /* box hugs its text; tops align, link track below */
    .gg-card__link  { grid-row: 6; margin-top: 0; justify-self: center; }
}

/* Empty state when a filter matches nothing in a band. */
.gg-band.is-empty { display: none; }
.gg-none {
    display: none;
    text-align: center;
    padding: 60px 0 20px;
    color: var(--gg-ink-soft);
}
.gg-none.is-on { display: block; }

/* --------------------------------------------------------------- events -- */

.gg-events { background: var(--gg-teal); color: #fff; margin-top: 80px; padding: 72px 0; }
.gg-events .gg-band { padding: 0; }
.gg-events .gg-band__title { color: #fff; }
.gg-events .gg-band__sub { color: #cfdcdd; }
/* The monogram mask inherits the white heading colour on this teal section via
   currentColor, so no override is needed here. */
/* MITEC calendar action, right-aligned beside the heading (the band head is a
   bottom-aligned flex row). flex:0 0 auto keeps it from being squeezed; on mobile
   the band head stacks to a column and the button drops under the subtitle. */
.gg-events__cal { flex: 0 0 auto; }

.gg-eventgrid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
    gap: 22px;
}
.gg-event {
    display: grid;
    grid-template-columns: 128px 1fr;
    background: rgba(255,255,255,.06);
    border: 1px solid rgba(255,255,255,.13);
    border-radius: var(--gg-radius);
    overflow: hidden;
}
.gg-event__media { position: relative; background: rgba(255,255,255,.09); }
.gg-event__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gg-event__body { padding: 18px 20px; }
.gg-event__tag {
    display: inline-block;
    font: 10px/1 untitled-bold, untitled, sans-serif;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--gg-mustard-l);
    margin-bottom: 9px;
}
.gg-event__name { font-size: 21px; line-height: 1.15; color: #fff; margin-bottom: 8px; }
.gg-event__meta { font-size: 13px; color: #cfdcdd; }
.gg-event__meta span { display: block; }
.gg-event__link {
    display: inline-flex; align-items: center; gap: 7px;
    margin-top: 12px;
    font: 11px/1 untitled-bold, untitled, sans-serif;
    letter-spacing: 0.15em; text-transform: uppercase;
    color: var(--gg-mustard-l); text-decoration: none;
}
.gg-event__link:hover { color: #fff; text-decoration: none; }

/* Shown when no event is currently running. Keeps the section honest
   rather than leaving stale "dates to be confirmed" cards on the page. */
.gg-events__quiet {
    display: flex; flex-wrap: wrap; align-items: center; gap: 18px;
    background: rgba(255,255,255,.06);
    border: 1px solid rgba(255,255,255,.13);
    border-radius: var(--gg-radius);
    padding: 26px 28px;
    color: #cfdcdd;
}

/* ------------------------------------------------------------------ cta -- */

.gg-cta { padding: 86px 0 96px; text-align: center; }
.gg-cta__card {
    position: relative;
    background: var(--gg-cream-d);
    border-radius: 22px;
    padding: 66px 34px;
    overflow: hidden;
}
.gg-cta__title {
    font-size: clamp(26px, 3.2vw, 41px);
    line-height: 1.1;
    color: var(--gg-teal);
    margin-bottom: 16px;
}
.gg-cta__body {
    color: var(--gg-ink-soft);
    font-size: 16px;
    max-width: 33em;
    margin: 0 auto 30px;
}
.gg-cta__actions { display: flex; justify-content: center; flex-wrap: wrap; gap: 14px; }
/* Soft AMI-monogram watermark on the CTA card (the real logo mark, masked, faint). */
.gg-cta__arch {
    position: absolute;
    width: 200px; height: 333px;   /* 0.601 w/h keeps the monogram's aspect */
    background-color: var(--gg-mustard);
    -webkit-mask: url('../img/guide/ami-arch-teal.png') no-repeat center / contain;
    mask: url('../img/guide/ami-arch-teal.png') no-repeat center / contain;
    opacity: .14;
    right: -30px; bottom: -96px;
    pointer-events: none;
}

/* -------------------------------------------------------------- footer -- */
/* Standard site footer (footer.php) reverted onto this page (WL, 2026-08-26).
   footer.php is a fullPage `.section` slide; on the pages that run fullPage its
   dark background comes from `sectionsColor`. This page does NOT run fullPage, so
   the section would otherwise be transparent and its white text/links would
   vanish on the cream body. Paint the teal ground here, and give it some air from
   the CTA above. The guest-reviews owl carousel is initialised by js.php. */
#section-footer {
    background: var(--gg-teal);
    margin-top: 84px;
}

/* Slim bespoke footer (inc/gg-footer.php) — currently NOT used (WL reverted to the
   standard footer above). Styles kept so switching back is a one-line include swap. */
.gg-footer {
    background: var(--gg-teal);
    color: #dfe8e9;
    padding: 46px 0 42px;
}
.gg-footer__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 18px 40px;
}
.gg-footer__brand { display: flex; align-items: center; gap: 12px; }
.gg-footer__arch {
    width: 26px; height: 34px;
    border: 2px solid var(--gg-mustard-l);
    border-bottom: 0;
    border-radius: 999px 999px 4px 4px;
    flex: 0 0 auto;
}
.gg-footer__word {
    font-family: recoleta-semibold, recoleta, serif;
    font-size: 22px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: #fff;
}
.gg-footer__nap {
    font-style: normal;
    font-size: 13px;
    line-height: 1.6;
    color: #cfdcdd;
    flex: 1 1 260px;
}
.gg-footer__contact { display: block; margin-top: 6px; }
.gg-footer__nap a {
    color: var(--gg-mustard-l);
    text-decoration: none;
    margin-right: 16px;
}
.gg-footer__nap a:hover { color: #fff; }
.gg-footer__links { display: flex; flex-wrap: wrap; gap: 8px 20px; }
.gg-footer__links a {
    color: #fff;
    text-decoration: none;
    font: 12px/1 untitled-bold, untitled, sans-serif;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    cursor: pointer;
}
.gg-footer__links a:hover { color: var(--gg-mustard-l); }
.gg-footer__social { display: flex; align-items: center; gap: 14px; }
.gg-footer__social img { width: 22px; height: 22px; display: block; }
.gg-footer__social a:hover img { opacity: .8; }
.gg-footer__copy {
    flex-basis: 100%;
    margin: 6px 0 0;
    font-size: 12px;
    color: #93a9ab;
}

/* Data-integrity banner (localhost / staging only; see the-good-guide.php). */
.gg-audit {
    position: fixed;
    left: 12px; bottom: 12px;
    z-index: 1200;
    max-width: min(440px, 92vw);
    background: #7a1f1f;
    color: #fff;
    font: 12px/1.45 ui-monospace, Menlo, Consolas, monospace;
    padding: 10px 14px;
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0,0,0,.32);
}
.gg-audit strong { font-weight: 700; }

/* --------------------------------------------------------- motion states -- */
/* Applied only when html carries .gg-motion, which the page sets in an inline
   script and only when the visitor has not asked for reduced motion. Without
   that class every element renders in its final state, so no-JS and
   reduced-motion visitors see a complete page. If GSAP is missing,
   good-guide.js strips .gg-motion (and .gg-anim-pre), so these all switch off
   and nothing stays hidden. */

/* Smooth in-page jumps, but only for visitors who have not asked for less
   motion, since gg-motion is absent in that case. */
html.gg-motion { scroll-behavior: smooth; }

html.gg-motion .gg-hero__eyebrow { opacity: 0; }
html.gg-motion .gg-hero__lede,
html.gg-motion .gg-hero__actions { opacity: 0; transform: translateY(18px); }
/* Hidden until SplitText has finished cutting it up, otherwise the whole
   headline flashes in unsplit for a frame before the animation starts. */
html.gg-motion .gg-hero__title { opacity: 0; }
html.gg-motion .gg-reveal { opacity: 0; transform: translateY(26px); }
/* Card entrance pre-hide. Scoped :not(.gg-shown): once good-guide.js has revealed
   a card it adds .gg-shown and clears the inline styles GSAP left, so the card
   rests on plain CSS with NO inline transform — otherwise a leftover
   transform:translate(0,0) would override the :hover / .is-linked lift below.
   Non-motion paths never carry .gg-motion, so this never hides anything there. */
html.gg-motion .gg-card:not(.gg-shown) { opacity: 0; transform: translateY(30px); }

/* MAP entrance (Phase 3). The map assembles on load — plate fades in, the AMI
   centre mark settles, the rings draw themselves in and the pins pop. It is
   pre-hidden ONLY while html carries BOTH .gg-motion and the ephemeral
   .gg-anim-pre (set together in the inline <head> script). good-guide.js drops
   .gg-anim-pre the instant the entrance finishes, so the pre-hide never persists
   and the map's own hover / active / dim transforms take back over. Pure OPACITY
   only here — no pre-set transforms or stroke-dashes — so even a browser that
   cannot measure the ring stroke, or one where JS/GSAP never runs, shows a
   complete map (all 25 pins, 3 rings, centre, captions). The stroke draw-in and
   the dot pop are layered on in JS and clear themselves afterwards. */
html.gg-motion.gg-anim-pre .gg-map__plate,
html.gg-motion.gg-anim-pre .gg-map__center,
html.gg-motion.gg-anim-pre .gg-ring,
html.gg-motion.gg-anim-pre .gg-ring-halo,
html.gg-motion.gg-anim-pre .gg-ring-cap,
html.gg-motion.gg-anim-pre .gg-pin { opacity: 0; }

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

/* --------------------------------------------------------------- mobile -- */

@media (max-width: 1024px) {
    .gg-hero__inner { grid-template-columns: 1fr; gap: 34px; }
    /* Portrait-ish map on stacked layouts. Same coordinate model; the taller
       box just reshapes the ring ellipses. */
    .gg-hero__map { max-width: 520px; margin: 0 auto; width: 100%; }
    .gg-map__stage { aspect-ratio: 4 / 4.35; }
    /* Portrait plate for the tall mobile stage. Same fallback-gradient rule:
       the WebP is the top layer, the cream gradient shows if it is absent. */
    .gg-map__plate {
        background:
            url('../img/guide/map-backdrop-mobile.jpg') center / cover no-repeat,
            radial-gradient(120% 118% at 50% 56%, #fcf9f2 0%, #f3edde 52%, #e8dfd0 100%);
        background:
            image-set(url('../img/guide/map-backdrop-mobile.webp') type('image/webp'),
                      url('../img/guide/map-backdrop-mobile.jpg') type('image/jpeg')) center / cover no-repeat,
            radial-gradient(120% 118% at 50% 56%, #fcf9f2 0%, #f3edde 52%, #e8dfd0 100%);
    }

    /* The portrait map is too small to carry many venue labels at once — a broad
       category (Eat, Coffee) matches a dozen listings and their labels would
       pile up and run off the edges. So on stacked layouts an active category
       enlarges the matching DOTS but does not auto-reveal their labels; the
       names still live in the filtered cards below, and tapping a pin reveals
       its name and jumps to its card. Re-assert the tap/focus/link reveal after
       the suppression so a single tapped pin still shows its label. */
    .gg-pin.is-match .gg-pin__label {
        opacity: 0; visibility: hidden; transform: translate(-50%, -3px);
    }
    .gg-pin.is-linked .gg-pin__label,
    .gg-pin:focus-visible .gg-pin__label {
        opacity: 1; visibility: visible; transform: translate(-50%, 0);
    }
}

@media (max-width: 768px) {
    .gg-wrap { padding: 0 20px; }
    .gg-hero { padding: 116px 0 16px; }
    .gg-filters--hero { margin-top: 30px; }
    .gg-hero__lede { font-size: 15px; }
    .gg-intro { padding: 62px 0 4px; }
    .gg-band { padding: 46px 0 6px; }
    .gg-band__head { flex-direction: column; align-items: flex-start; gap: 12px; }

    /* Chips become a swipeable rail rather than wrapping to three rows.
       Negative margins let it bleed to the screen edge so it reads as
       scrollable without a scrollbar hint. */
    .gg-chips {
        justify-content: flex-start;
        flex-wrap: nowrap;
        overflow-x: auto;
        scroll-snap-type: x proximity;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        margin: 0 -20px;
        padding: 4px 20px 14px;
    }
    .gg-chips::-webkit-scrollbar { display: none; }
    .gg-chip { scroll-snap-align: start; }

    .gg-grid { grid-template-columns: 1fr; gap: 20px; }
    .gg-eventgrid { grid-template-columns: 1fr; }
    .gg-event { grid-template-columns: 104px 1fr; }
    .gg-cta { padding: 62px 0 84px; }
    .gg-cta__card { padding: 48px 22px; }

    .gg-footer__inner { gap: 16px 28px; }
}

@media (max-width: 480px) {
    .gg-hero__title-l1 { line-height: 0.98; }
    .gg-hero__map { max-width: 420px; }
    .gg-map__stage { aspect-ratio: 4 / 4.6; }
}
