/* ============================================================
   XC_Travel_v1.css — TravelTips/List and TravelTips/Detail

   Additive, like XC_Auth_v1.css and XC_Tracker_v1.css: it redefines
   no token and no .btn. It sits on top of

       XC_Home_v4.css   tokens, .btn, .wrap, .section, .band, .rise,
                        .num, .sr-only, masthead, footer

   and adds only the destination index — the page head, the filter
   bar, and the plate.

   THESIS. This is not a photo gallery of nice places. It is the index
   of every destination Xc Exchange can put cash in your hand for, so
   each entry prints the currency of the place and today's rate for it
   beside the picture rather than hiding both a click away. The
   photograph earns the click; the rate line is why this page belongs
   to a currency house and not to a travel blog.

   FORM. A contact sheet, not a card grid. The photograph is the only
   filled object; the caption beneath it sits on the page ground,
   ruled off by a hairline, the way a plate is captioned in print.
   That keeps the house rule — cards are not a structural device —
   while letting the photography do the work an index of places needs
   it to do.

   COLOUR LOGIC. Blue is structure: the rule under a plate on hover,
   the read-the-guide arrow, the active filter. Amber is reserved for
   the rate figure, which is the one number on the page that moves and
   the only reason a traveller is reading an index rather than a map.
   Neutrals carry everything else so the photographs are the
   only colour competing.
   ============================================================ */

/* ============================================================
   PAGE HEAD

   Asymmetric on purpose: the ask on the left at reading measure, the
   two standing facts on the right in mono, hairline-ruled off it.
   They are a count and a timestamp, not a metric display — they answer
   "how much of this is there, and how fresh is it".
   ============================================================ */
.tt-head {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: 3rem;
  align-items: end;
  padding-bottom: 2.25rem;
}

.tt-head h1 {
  /* the ask is one sentence and reads as one line: the size scales with the
     viewport instead of wrapping, so "Where are you going?" never breaks */
  /* Inter sets this line about 16% wider than Source Serif did, which
     left 9px of slack at the two-column breakpoint -- one stray metric
     from wrapping. The sizes come down to put the room back. */
  font-size: clamp(1.5rem, 6.4vw, 2.8rem);
  line-height: 1.04;
  letter-spacing: -.022em;
  color: var(--ink);
  white-space: nowrap;
}

.tt-lede {
  margin-top: 1.15rem;
  font-size: clamp(15px, 1.15vw, 16.5px);
  line-height: 1.62;
  color: var(--body);
  max-width: 54ch;
}

.tt-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.75rem;
  margin: 0;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line-strong);
}
.tt-facts dt {
  font-family: var(--f-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .01em;
  /* the house label voice is --muted (DESIGN.md, Type), but --muted on
     --ground measures 3.92:1 and this is text a reader has to read. The
     voice is the font, size, tracking and case; the colour steps up one
     token to clear 4.5:1. The same swap is owed to .eyebrow system-wide. */
  color: var(--body);
}
.tt-facts dd {
  margin: .45rem 0 0;
  font-family: var(--f-mono);
  font-size: 14px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--ink);
}

/* ============================================================
   FILTER BAR

   One row: the search field, the region buttons, the live count.
   Not sticky. A sticky bar on a page whose whole body is one grid
   buys nothing and can sit over a keyboard-focused plate, which is
   the failure WCAG 2.2 names focus-not-obscured.
   ============================================================ */
.tt-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem 1.25rem;
  padding-bottom: 1.1rem;
  border-bottom: 1px solid var(--line);
}

.tt-search {
  position: relative;
  flex: 0 1 302px;
  display: flex;
  align-items: center;
}
.tt-search-icn {
  position: absolute;
  left: .68rem;
  width: 15px;
  height: 15px;
  color: var(--muted);
  pointer-events: none;
  transition: color .18s ease;
}
.tt-search input {
  width: 100%;
  font-family: var(--f-ui);
  font-size: 14px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  padding: .58rem 2.1rem .58rem 2.1rem;
  transition: border-color .18s ease, box-shadow .18s ease;
  -webkit-appearance: none;
  appearance: none;
}
.tt-search input::placeholder { color: var(--muted); }
.tt-search input:hover { border-color: var(--muted); }
.tt-search input:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(0, 0, 255, .1);
}
.tt-search input:focus-visible { outline: 2px solid var(--accent-fill); outline-offset: 2px; }
.tt-search:focus-within .tt-search-icn { color: var(--brand); }

/* the browser's own clear affordance is removed so the drawn one is
   the only one, and so the field does not carry two crosses */
.tt-search input::-webkit-search-cancel-button,
.tt-search input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }

.tt-search-clear {
  position: absolute;
  right: .3rem;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  padding: 0;
  color: var(--muted);
  background: none;
  border: 0;
  border-radius: var(--r);
  cursor: pointer;
  transition: color .18s ease, background-color .18s ease;
}
.tt-search-clear svg { width: 13px; height: 13px; }
.tt-search-clear:hover { color: var(--ink); background: var(--surface-2); }

.tt-regions {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin-right: auto;
}
.tt-chip {
  font-family: var(--f-ui);
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1;
  color: var(--body);
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  /* 24px CSS px is the WCAG 2.2 floor; this clears it in both axes */
  padding: .58rem .7rem;
  cursor: pointer;
  white-space: nowrap;
  transition: color .18s ease, background-color .18s ease, border-color .18s ease;
}
.tt-chip:hover { color: var(--ink); background: var(--surface-2); border-color: var(--muted); }
.tt-chip.is-on {
  color: var(--surface);
  background: var(--brand);
  border-color: var(--brand);
}

.tt-count {
  font-family: var(--f-mono);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: .04em;
  /* --body, not --muted: on the light ground --muted lands at 3.92:1,
     and this line is a live result count, not a field label */
  color: var(--body);
  white-space: nowrap;
}

/* ============================================================
   THE INDEX

   auto-fill rather than auto-fit: with one destination left after a
   filter, auto-fit stretches it across the full 1240px and the page
   reads as broken. auto-fill keeps the column width the grid
   promised and leaves the empty tracks empty.
   ============================================================ */
.tt-index-wrap { padding: 2.25rem 0 4.5rem; }

.tt-index {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(258px, 1fr));
  gap: 2.5rem 1.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tt-item.is-out { display: none; }

.tt-plate {
  display: grid;
  grid-template-rows: auto 1fr;
  gap: .85rem;
  text-decoration: none;
  color: inherit;
}

/* ---------- the photograph ---------- */
.tt-shot {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--r);
  border: 1px solid var(--line);
  background: var(--surface-2);
}
/* the direct child only: the stamp's flag is also an img inside
   .tt-shot, and a descendant selector here sizes it to the plate */
.tt-shot > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transform: scale(1.001);
  transition: transform .5s cubic-bezier(.22, .61, .36, 1), filter .35s ease;
}

/* a floor of contrast under the stamp, drawn only where the stamp
   sits — a veil across the whole photograph would flatten every
   picture to make room for one small label */
.tt-shot::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 42%;
  background: linear-gradient(to top, rgba(0, 6, 46, .46), rgba(0, 6, 46, 0));
  opacity: 0;
  transition: opacity .35s ease;
  pointer-events: none;
}
/* on its own, never grouped: a browser without :has() must drop this
   rule alone. The stamp is legible without the gradient anyway — it
   carries its own sheet and hairline — so the absence degrades to
   "slightly less grounded", not to "unreadable". */
.tt-shot:has(.tt-stamp)::after { opacity: 1; }

/* currency stamp — flag plus code, the destination's money named on
   the picture itself */
.tt-stamp {
  position: absolute;
  left: .55rem;
  bottom: .55rem;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: .38rem;
  padding: .27rem .45rem;
  border-radius: var(--r);
  background: rgba(255, 255, 255, .93);
  border: 1px solid rgba(0, 6, 46, .12);
  box-shadow: 0 1px 3px rgba(0, 10, 77, .22);
  /* the sheet is near-white in both themes, so the stamp fixes its own
     ink rather than inheriting a light one in dark mode */
  color: #05082A;
}
.tt-stamp .num {
  font-family: var(--f-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .06em;
  line-height: 1;
  color: #05082A;
}
.tt-flag {
  display: block;
  width: 20px;
  height: 14px;
  object-fit: cover;
  border-radius: 1px;
}

/* ---------- the caption ---------- */
.tt-body {
  display: grid;
  align-content: start;
  gap: .3rem;
  padding-top: .7rem;
  border-top: 1px solid var(--line-strong);
  position: relative;
}

/* the hairline the caption hangs from becomes brand blue on hover,
   drawn from the left. The one authored moment on this surface, and
   it moves a transform, never a width. */
.tt-body::before {
  content: "";
  position: absolute;
  inset: -1px 0 auto 0;
  height: 1px;
  background: var(--brand);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .42s cubic-bezier(.22, .61, .36, 1);
}

.tt-titleline {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .6rem;
}
.tt-name {
  font-family: var(--f-display);
  font-size: 18.5px;
  font-weight: 600;
  letter-spacing: -.012em;
  line-height: 1.2;
  color: var(--ink);
  transition: color .18s ease;
}
/* the affordance, carried by the name instead of by a repeated CTA
   line. Always drawn — an arrow that only exists on hover tells a
   touch user nothing — and it travels on hover. */
.tt-arw {
  width: 12px;
  height: 12px;
  margin-left: .3rem;
  vertical-align: baseline;
  color: var(--muted);
  transition: transform .28s cubic-bezier(.22, .61, .36, 1), color .18s ease;
}
.tt-region {
  font-family: var(--f-mono);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: .01em;
  color: var(--body);
  white-space: nowrap;
  flex: none;
}

/* the rate. Amber is the figure and only the figure. */
.tt-rate {
  font-family: var(--f-mono);
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--body);
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: .3rem;
}
.tt-rate-from { font-weight: 500; letter-spacing: .02em; }
.tt-rate b {
  font-size: 15.5px;
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--ink);
  /* the amber is the underline beneath the figure, not the figure's
     own colour: amber is never body text on light */
  box-shadow: inset 0 -.34em 0 var(--accent-wash);
}
.tt-rate-code { font-weight: 500; color: var(--body); }
.tt-rate-none { font-style: normal; color: var(--body); }

/* ---------- states ---------- */
.tt-plate:hover .tt-shot > img { transform: scale(1.055); }
.tt-plate:hover .tt-body::before { transform: scaleX(1); }
.tt-plate:hover .tt-arw { transform: translateX(3px); color: var(--brand); }
.tt-plate:hover .tt-name { color: var(--brand); }

/* the focus ring belongs on the whole plate, not on the anchor's
   inline box, or a keyboard user sees a ring around the caption and
   no indication which photograph they are on */
.tt-plate:focus-visible {
  outline: 2px solid var(--accent-fill);
  outline-offset: 4px;
  border-radius: var(--r);
}
.tt-plate:focus-visible .tt-body::before { transform: scaleX(1); }

/* ============================================================
   EMPTY STATE
   ============================================================ */
.tt-empty {
  margin-top: 1rem;
  padding: 2.4rem 1.75rem;
  text-align: center;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
}
.tt-empty-h {
  font-family: var(--f-display);
  font-size: 19px;
  font-weight: 600;
  color: var(--ink);
}
.tt-empty-h b { font-weight: 600; color: var(--brand); }
.tt-empty-p {
  margin: .6rem auto 0;
  max-width: 46ch;
  font-size: 14px;
  line-height: 1.6;
  color: var(--body);
}
.tt-empty-act {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .6rem;
  margin-top: 1.35rem;
}

/* ============================================================
   CLOSING BAND
   Two columns on the navy field, same construction as the home
   page's bands so the page closes in the house's voice.
   ============================================================ */
.tt-band-in,
.td-band-in {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2rem 3rem;
  align-items: center;
  padding: 3rem 0;
}
.tt-band-in h2,
.td-band-in h2 {
  font-size: clamp(1.4rem, 2.3vw, 1.95rem);
  color: var(--on-navy);
}
.tt-band-in p,
.td-band-in p {
  margin-top: .7rem;
  max-width: 58ch;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--on-navy-dim);
}
.tt-band-act,
.td-band-act { display: flex; flex-wrap: wrap; gap: .6rem; }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 1000px) {
  .tt-head {
    grid-template-columns: 1fr;
    gap: 1.9rem;
    align-items: start;
  }
  .tt-facts { gap: 1rem; }
}

@media (max-width: 760px) {
  .tt-index { grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); gap: 2rem 1.25rem; }
  .tt-filter { gap: .7rem; }
  .tt-search { flex: 1 1 100%; }
  .tt-regions { margin-right: 0; }
  .tt-count { width: 100%; }
  .tt-band-in,
  .td-band-in { grid-template-columns: 1fr; padding: 2.4rem 0; }
}

@media (max-width: 520px) {
  /* one column below this: two 150px-wide photographs side by side
     stop being photographs of anywhere */
  .tt-index { grid-template-columns: 1fr; gap: 1.9rem; }
  /* one column: at this width "24 destinations, 24 priced" breaks
     mid-phrase in a half-width track while the other half sits empty */
  .tt-facts { grid-template-columns: 1fr; row-gap: 1.05rem; }
  .tt-band-act .btn { flex: 1 1 auto; justify-content: center; }
}

/* ============================================================
   REDUCED MOTION
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .tt-shot > img,
  .tt-body::before,
  .tt-arw,
  .tt-search-icn,
  .tt-chip,
  .tt-search input { transition-duration: .01ms; }
  .tt-plate:hover .tt-shot > img { transform: none; }
  .tt-body::before { transform: scaleX(1); background: var(--line-strong); }
  .tt-plate:hover .tt-body::before { background: var(--brand); }
}

/* ============================================================
   ============================================================
   TravelTips/Detail — one destination guide
   ============================================================

   THESIS. A destination guide written by a currency house has one
   thing a travel blog does not: the rate. So every local price is
   printed twice — what the guide records locally, and what that
   costs in Australian dollars at today's server-priced rate. The
   photograph sets the place; the second column is the reason the
   page belongs to us.

   FORM. An asymmetric opener: the money on the left at reading
   measure, the place on the right. Below it, three plain measures —
   a fact list, a table and a numbered list — separated by hairlines
   and nothing else. No panel, no tile, no card. The only filled
   objects on the page are the photographs and the two buttons.

   COLOUR LOGIC. Identical to the index. Blue is structure and the
   icon set; amber is spent only on figures that move — the rate and
   the Australian column — and always as a wash under the number,
   never as ink.
   ============================================================ */

/* the browser's own surfaces belong to the design too */
.td-hero ::selection,
.td-money ::selection,
.td-costs ::selection,
.td-tips-wrap ::selection,
.td-gal-wrap ::selection { background: var(--accent-fill); color: var(--accent-ink); }

/* ------------------------------------------------------------
   OPENER
   ------------------------------------------------------------ */
.td-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.02fr);
  gap: clamp(2rem, 4vw, 4rem);
  align-items: center;
  padding-top: clamp(2.4rem, 4vw, 3.6rem);
  padding-bottom: clamp(2.6rem, 4vw, 4rem);
}

.td-crumb {
  display: flex;
  align-items: center;
  gap: .45rem;
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: .07em;
  color: var(--body);
}
.td-crumb svg { width: 11px; height: 11px; color: var(--muted); flex: none; }
.td-crumb a {
  text-decoration: none;
  color: var(--body);
  border-bottom: 1px solid var(--line-strong);
  padding-bottom: 1px;
  transition: color .18s ease, border-color .18s ease;
}
.td-crumb a:hover { color: var(--brand); border-bottom-color: var(--brand); }
.td-crumb [aria-current] { color: var(--ink); }

.td-hero h1 {
  margin-top: 1.15rem;
  font-size: clamp(2.35rem, 5.4vw, 4.1rem);
  line-height: .98;
  letter-spacing: -.028em;
  color: var(--ink);
}

.td-lede {
  margin-top: 1.1rem;
  max-width: 46ch;
  font-size: clamp(15px, 1.2vw, 16.5px);
  line-height: 1.62;
  color: var(--body);
}

/* the one figure the page exists to attach to a place */
.td-rate {
  margin-top: clamp(1.6rem, 3vw, 2.3rem);
  padding-top: 1.35rem;
  border-top: 1px solid var(--line-strong);
}
.td-rate-fig {
  font-family: var(--f-mono);
  font-size: clamp(1.45rem, 3vw, 2.1rem);
  line-height: 1.1;
  letter-spacing: -.02em;
  color: var(--body);
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: .4rem;
}
.td-rate-from { font-size: .5em; font-weight: 500; letter-spacing: .02em; }
.td-rate-fig b {
  font-weight: 600;
  color: var(--ink);
  /* amber as a wash under the figure, never as ink on light */
  box-shadow: inset 0 -.3em 0 var(--accent-wash);
}
.td-rate-code { font-size: .52em; font-weight: 500; letter-spacing: .04em; }
.td-rate-none { color: var(--body); }
.td-rate-note {
  margin-top: .65rem;
  font-family: var(--f-mono);
  font-size: 11.5px;
  line-height: 1.55;
  letter-spacing: .01em;
  color: var(--body);
  max-width: 48ch;
}
.td-rate-act {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  margin-top: 1.35rem;
}

.td-shot { position: relative; margin: 0; }
.td-shot picture {
  display: block;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r);
}
.td-shot picture img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  /* the one authored moment on this surface: the place settles into
     place once, on arrival. Transform and opacity only. */
  animation: td-settle .9s cubic-bezier(.16, 1, .3, 1) both;
}
@keyframes td-settle {
  from { transform: scale(1.055); opacity: .001; }
  to   { transform: none;         opacity: 1; }
}

/* same stamp as the index plates, so a destination is labelled the
   same way whether it is one of twenty-four or on its own page */
.td-stamp {
  position: absolute;
  left: .7rem;
  bottom: .7rem;
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .35rem .55rem;
  background: rgba(255, 255, 255, .93);
  color: #05082A;
  border-radius: var(--r);
  font-family: var(--f-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .06em;
}
.td-flag {
  width: 20px;
  height: 14px;
  object-fit: cover;
  border-radius: 1px;
  display: block;
}
.td-stamp-sep {
  width: 1px;
  height: 11px;
  background: rgba(5, 8, 42, .28);
}

/* ------------------------------------------------------------
   SECTIONS — hairline separation, nothing else
   ------------------------------------------------------------ */
.td-money,
.td-costs,
.td-tips-wrap,
.td-gal-wrap { border-top: 1px solid var(--line); }

.td-sec-head {
  max-width: 64ch;
  margin-bottom: clamp(1.5rem, 2.6vw, 2.1rem);
}
.td-sec-head h2 {
  font-size: clamp(1.5rem, 2.7vw, 2.15rem);
  line-height: 1.12;
  letter-spacing: -.02em;
}
.td-sec-head p {
  margin-top: .8rem;
  font-size: 15px;
  line-height: 1.62;
  color: var(--body);
}

/* ------------------------------------------------------------
   THE MONEY
   ------------------------------------------------------------ */
.td-money-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: start;
}

.td-facts { margin: 0; }
.td-facts > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.25rem;
  padding: .85rem 0;
  border-bottom: 1px solid var(--line);
}
.td-facts > div:first-child { border-top: 1px solid var(--line-strong); }
.td-facts dt {
  font-family: var(--f-mono);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: .01em;
  /* --muted measures 3.92:1 on --ground; label text steps up to --body */
  color: var(--body);
}
.td-facts dd {
  margin: 0;
  font-size: 15px;
  font-weight: 500;
  color: var(--ink);
  text-align: right;
}

.td-dens h3 {
  font-family: var(--f-mono);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: .01em;
  color: var(--body);
}
.td-den-list {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  list-style: none;
  padding: 0;
  margin: .75rem 0 1.6rem;
}
.td-den-list li {
  padding: .42rem .72rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--ink);
  font-family: var(--f-mono);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: .02em;
}
/* coins are context, not stock: the same object, unfilled */
.td-den-coins li {
  background: none;
  border-color: var(--line);
  color: var(--body);
}
.td-den-note {
  max-width: 48ch;
  font-size: 13px;
  line-height: 1.6;
  color: var(--body);
}

/* ------------------------------------------------------------
   WHAT THINGS COST — the local figure, and the same figure in AUD
   ------------------------------------------------------------ */
.td-cost {
  width: 100%;
  border-collapse: collapse;
}
.td-cost th,
.td-cost td {
  text-align: left;
  padding: .95rem .9rem;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
.td-cost th:first-child,
.td-cost td:first-child { padding-left: 0; }
.td-cost th:last-child,
.td-cost td:last-child { padding-right: 0; }

.td-cost thead th {
  font-family: var(--f-mono);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: .01em;
  color: var(--body);
  padding-block: .55rem;
  border-bottom: 1px solid var(--line-strong);
}

/* the icon and the label share an inner flex line rather than turning the
   cell itself into a flex container: a th that stops being a table-cell
   stops sharing the row height, and each cell then paints its hairline at
   its own baseline */
.td-cost tbody th.td-cost-what {
  font-family: var(--f-ui);
  font-size: 14.5px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--ink);
}
.td-cost-lineup {
  display: flex;
  align-items: center;
  gap: .8rem;
}
.td-cost-icn {
  width: 20px;
  height: 20px;
  flex: none;
  color: var(--brand);
}

.td-cost .td-cost-local,
.td-cost .td-cost-aud { text-align: right; white-space: nowrap; }
/* the two figure columns are held narrow and to the right, so a number
   never drifts a third of the page away from the label it belongs to */
.td-cost .td-cost-local { width: 17%; color: var(--body); font-size: 14.5px; }
.td-cost .td-cost-aud { width: 19%; }
.td-cost-aud b {
  font-weight: 600;
  font-size: 15.5px;
  color: var(--ink);
  box-shadow: inset 0 -.32em 0 var(--accent-wash);
}
.td-cost-none { color: var(--body); }

/* the column label rides each figure only in the stacked layout */
.td-cost-lbl { display: none; }

.td-cost tbody tr { transition: background-color .16s ease; }
.td-cost tbody tr:hover th,
.td-cost tbody tr:hover td { background: var(--surface); }

.td-cost-foot {
  margin-top: 1.15rem;
  max-width: 70ch;
  font-size: 13px;
  line-height: 1.62;
  color: var(--body);
}

/* ------------------------------------------------------------
   BEFORE YOU GO
   ------------------------------------------------------------ */
.td-tips {
  list-style: none;
  counter-reset: td-tip;
  padding: 0;
  margin: 0;
  max-width: 80ch;
}
.td-tips li {
  counter-increment: td-tip;
  position: relative;
  padding: 1.05rem 0 1.05rem 2.9rem;
  border-bottom: 1px solid var(--line);
  font-size: 15.5px;
  line-height: 1.62;
  color: var(--body);
}
.td-tips li:first-child { border-top: 1px solid var(--line-strong); }
.td-tips li::before {
  content: counter(td-tip);
  position: absolute;
  left: 0;
  top: 1.2rem;
  font-family: var(--f-mono);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: .04em;
  color: var(--brand);
}

/* ------------------------------------------------------------
   THE PLACE — the no-script floor: a scroll strip. The deck that
   replaces it once the script runs is at the foot of this file.
   ------------------------------------------------------------ */
.td-gal-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem;
  margin-bottom: 1.6rem;
}
.td-gal-head h2 {
  font-size: clamp(1.5rem, 2.7vw, 2.15rem);
  line-height: 1.12;
  letter-spacing: -.02em;
}
.td-gal-nav { display: flex; gap: .5rem; flex: none; }
.td-gal-btn {
  /* 44px, not the 38 this was: under 44 the button sits below the
     touch floor, and these two are the whole pointer-only way
     through the deck on a phone */
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  transition: color .18s ease, border-color .18s ease, background-color .18s ease;
}
.td-gal-btn svg { width: 17px; height: 17px; }
.td-gal-btn:hover { color: var(--brand); border-color: var(--brand); }
.td-gal-btn:active { transform: scale(.94); }
.td-gal-btn[disabled] { color: var(--muted); border-color: var(--line); cursor: default; }
.td-gal-btn[disabled]:hover { color: var(--muted); border-color: var(--line); }

.td-gal {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(270px, 33.5%);
  gap: 1.25rem;
  list-style: none;
  margin-inline: auto;
  margin-block: 0;
  padding: 0 0 1.1rem;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-behavior: smooth;
  /* the scrollbar is part of this component, not a browser default */
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) var(--surface-2);
}
.td-gal::-webkit-scrollbar { height: 6px; }
.td-gal::-webkit-scrollbar-track { background: var(--surface-2); border-radius: 3px; }
.td-gal::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 3px; }
.td-gal::-webkit-scrollbar-thumb:hover { background: var(--muted); }
.td-gal:focus-visible { outline: 2px solid var(--accent-fill); outline-offset: 6px; }

.td-gal > li { scroll-snap-align: start; }
.td-gal figure { margin: 0; }
.td-gal img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border: 1px solid var(--line);
  border-radius: var(--r);
}
.td-gal figcaption {
  margin-top: .65rem;
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: .05em;
  color: var(--body);
}

/* ------------------------------------------------------------
   RESPONSIVE
   ------------------------------------------------------------ */
@media (max-width: 1000px) {
  .td-hero {
    grid-template-columns: 1fr;
    gap: 1.9rem;
  }
  /* the place first at this width: the photograph is the fastest way
     to confirm you are on the right guide */
  .td-shot { order: -1; }
  .td-shot picture img { aspect-ratio: 16 / 9; }
}

@media (max-width: 900px) {
  .td-money-grid { grid-template-columns: 1fr; }
}

@media (max-width: 620px) {
  /* the table stacks: each row keeps its name on one line and puts the
     two figures side by side underneath, each carrying its own label */
  .td-cost,
  .td-cost tbody,
  .td-cost tr,
  .td-cost th,
  .td-cost td { display: block; }
  .td-cost thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .td-cost tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 1rem;
    row-gap: .55rem;
    padding: 1.05rem 0;
    border-bottom: 1px solid var(--line);
  }
  .td-cost tbody tr:first-child { border-top: 1px solid var(--line-strong); }
  .td-cost th,
  .td-cost td { padding: 0; border: 0; }
  .td-cost tbody th.td-cost-what { grid-column: 1 / -1; }
  .td-cost .td-cost-local { width: auto; text-align: left; }
  .td-cost .td-cost-aud { width: auto; text-align: right; }
  .td-cost-lbl {
    display: inline;
    margin-right: .4rem;
    font-family: var(--f-mono);
    font-size: 12px;
    letter-spacing: .01em;
    color: var(--body);
  }
  .td-cost tbody tr:hover th,
  .td-cost tbody tr:hover td { background: none; }

  .td-gal { grid-auto-columns: minmax(230px, 82%); }
  .td-gal-head { flex-wrap: wrap; }
  .td-rate-act .btn,
  .td-band-act .btn { flex: 1 1 auto; justify-content: center; }
}

/* ------------------------------------------------------------
   REDUCED MOTION
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .td-shot picture img { animation: none; }
  .td-gal { scroll-behavior: auto; }
  .td-crumb a,
  .td-gal-btn,
  .td-cost tbody tr { transition-duration: .01ms; }
}

/* ------------------------------------------------------------
   THE DECK — the strip above, turned in perspective

   The scroll strip is the no-script floor and stays exactly as it
   is. Once xc-travel_v1.js runs it adds .is-deck and the same list
   becomes a deck of frames fanned away from the centre one, which
   opens full size. Only transform and opacity are animated, and the
   whole thing collapses back to a row of flat photographs under
   prefers-reduced-motion.
   ------------------------------------------------------------ */
.td-gal.is-deck {
  /* one card width drives the stage height and every offset, so the
     deck scales as one object rather than six loose numbers */
  --cw: clamp(240px, 34vw, 520px);
  /* the room the centre frame's shadow falls into, above and below.
     What used to be here was an 18%-of-a-card reflection band: it
     rendered in webkit only, it read as a pale smudge at any size,
     and it left the deck floating over 100px of nothing between the
     frames and the caption. */
  --pad: calc(var(--cw) * .13);
  /* how thick a frame is. It is a share of the card rather than a
     fixed slab so the edge does not turn into a plank on a phone. */
  --th: calc(var(--cw) * .016);
  display: block;
  position: relative;
  width: 100%;
  margin-inline: 0;
  height: calc(var(--cw) * .667 + var(--pad) * 2);
  padding: 0;
  overflow: hidden;
  /* 950px, not 1500: the shorter the perspective the wider the
     lens, and at 1500 the frames were being projected almost
     orthographically -- the turn was there in the transform and
     barely in the picture. This is the single value that decides
     whether the deck looks like a photograph of a deck or a diagram
     of one. */
  perspective: 950px;
  perspective-origin: 50% 50%;
  scroll-snap-type: none;
  overflow-x: hidden;
  touch-action: pan-y;
  cursor: grab;
  /* the ends of the deck dissolve instead of being guillotined by the
     overflow. Before this the outermost frame stopped at a hard
     vertical edge -- at 390px it was cut on both sides at once, 32px
     off one and 32px off the other -- which reads as a rendering
     fault rather than as the edge of a deck that carries on. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 10%, #000 90%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 10%, #000 90%, transparent 100%);
}
.td-gal.is-deck:active,
.td-gal.is-deck.is-dragging { cursor: grabbing; }

.td-gal.is-deck > li {
  position: absolute;
  top: var(--pad);
  left: 50%;
  width: var(--cw);
  margin-left: calc(var(--cw) / -2);
  scroll-snap-align: none;
  transform-origin: 50% 50%;
  /* the frame, its two edges and its floor shadow share one space.

     This is why the depth fade below is a custom property and not an
     opacity, and why the grade is a filter on the frame rather than
     on this element: opacity under 1 and filter are both grouping
     properties, and either one flattens a 3D context. Set them here
     and the edge faces collapse to nothing -- they are rotated a
     quarter turn, so flat means zero width. */
  transform-style: preserve-3d;
  transition:
    transform .62s cubic-bezier(.22, .61, .36, 1),
    opacity .4s ease,
    filter .45s ease;
  will-change: transform;
}
/* a finger is faster than any curve: while a drag is live the deck
   tracks it frame by frame, so the transition has to be off */
.td-gal.is-deck.is-dragging > li { transition: none; }
.td-gal.is-deck figcaption { display: none; }

/* THE EDGES

   What makes a turned rectangle read as an object rather than a
   picture of one is that you can see it has a side. Both faces hinge
   at their own edge of the frame and fold backward, so the frame
   itself occludes whichever one points away and the near one shows
   past its silhouette -- which is what a slab does when you turn it.
   No decision about which side is showing has to be made anywhere:
   the geometry decides, the way it would with a real object. */
.td-gal.is-deck figure {
  position: relative;
  transform-style: preserve-3d;
}
.td-gal.is-deck figure::before,
.td-gal.is-deck figure::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: var(--th);
  opacity: var(--fade);
  pointer-events: none;
  transition: opacity .4s ease;
}
/* the left edge, hinged on the frame's left */
.td-gal.is-deck figure::before {
  right: 100%;
  transform-origin: 100% 50%;
  transform: rotateY(-90deg);
  background: linear-gradient(90deg, var(--line-strong), var(--surface-3));
}
/* and the right, hinged on its right */
.td-gal.is-deck figure::after {
  left: 100%;
  transform-origin: 0 50%;
  transform: rotateY(90deg);
  background: linear-gradient(90deg, var(--surface-3), var(--line-strong));
}

/* THE FLOOR

   Laid flat with a quarter turn about X so it lies in the ground
   plane and runs away from the viewer, rather than being a dark shape
   stuck to the bottom of the frame. It turns with the frame because
   it shares its space, which is the whole reason the edges and this
   are inside the 3D context rather than painted on after. */
.td-gal.is-deck > li::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 4%;
  right: 4%;
  height: calc(var(--cw) * .18);
  transform-origin: 50% 0;
  transform: rotateX(-90deg);
  background: radial-gradient(ellipse at 50% 0%,
              rgba(0, 10, 77, .30), rgba(0, 10, 77, 0) 70%);
  opacity: var(--fade);
  pointer-events: none;
}

/* THE GRADE

   A rotateY fan turns each frame but keeps every one of them the same
   HEIGHT, so the deck read as a row of photographs that had been
   shoved rather than a stack you are looking into. Depth is carried
   on four axes at once instead -- size, distance, colour and focus --
   which is what makes the centre frame the subject and everything
   else plainly behind it. The turn only says which way the deck runs.

   Size and distance are arithmetic and live in xc-travel_v1.js, which
   writes the transform and a data-depth. Every appearance decision is
   here. Blur stays small: at 2.4px a frame reads as out of focus
   without turning into a smear, and it is set once per step rather
   than per pixel, so eleven frames stay smooth. */
.td-gal.is-deck > li {
  --dim: 1;
  --sat: 1;
  --soft: 0px;
  --fade: 1;
}
.td-gal.is-deck > li[data-depth="1"] { --dim: .94; --sat: .88; --soft: .4px;  --fade: .95; }
.td-gal.is-deck > li[data-depth="2"] { --dim: .88; --sat: .76; --soft: 1.1px; --fade: .88; }
.td-gal.is-deck > li[data-depth="3"] { --dim: .83; --sat: .66; --soft: 1.8px; --fade: .81; }
.td-gal.is-deck > li[data-depth="4"],
.td-gal.is-deck > li[data-depth="5"] { --dim: .79; --sat: .58; --soft: 2.4px; --fade: .74; }

.td-frame { display: block; text-decoration: none; }
.td-gal.is-deck .td-frame {
  position: relative;
  border-radius: var(--r);
  overflow: hidden;
  /* the grade rides here, on the one element in the frame that has no
     3D children of its own to flatten */
  filter: brightness(var(--dim)) saturate(var(--sat)) blur(var(--soft));
  opacity: var(--fade);
  box-shadow:
    0 14px 26px -20px rgba(0, 10, 77, .55),
    0 1px 2px rgba(0, 10, 77, .07);
  transition:
    box-shadow .45s ease,
    transform .3s cubic-bezier(.22, .61, .36, 1),
    filter .45s ease,
    opacity .4s ease;
}
/* a hairline inside the frame rather than a border drawn on top of
   it, so a photograph that runs pale at its edge still stops
   somewhere. The same hairline the rest of the page separates with. */
.td-gal.is-deck .td-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--r);
  box-shadow: inset 0 0 0 1px rgba(5, 10, 51, .15);
  pointer-events: none;
}
.td-gal.is-deck img { border: 0; }

/* the centre frame is the one that opens, and the only one lifted far
   enough off the ground to cast anything */
.td-gal.is-deck [data-active] .td-frame {
  cursor: zoom-in;
  box-shadow:
    0 42px 62px -34px rgba(0, 10, 77, .58),
    0 12px 22px -18px rgba(0, 10, 77, .30),
    0 2px 4px rgba(0, 10, 77, .08);
}
@media (hover: hover) {
  .td-gal.is-deck [data-active] .td-frame:hover {
    transform: scale(1.012);
    box-shadow:
      0 50px 70px -32px rgba(0, 10, 77, .60),
      0 14px 26px -18px rgba(0, 10, 77, .32),
      0 2px 4px rgba(0, 10, 77, .08);
  }
}
.td-gal.is-deck [data-active] .td-frame:active { transform: scale(.995); }
.td-frame:focus-visible { outline: 2px solid var(--accent-fill); outline-offset: 3px; }

/* one caption for the deck, under the centre frame */
.td-deck-cap {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  /* 1.15rem, not 1.35: the caption used to sit the far side of a
     reflection band that is gone, and at the old distance it read as
     a stray line rather than as this deck's label */
  margin-top: 1.15rem;
  font-family: var(--f-mono);
  font-size: 11.5px;
  letter-spacing: .06em;
  color: var(--body);
}
.td-deck-cap .num { color: var(--ink); flex: none; }
.td-deck-cap > span:first-child { flex: none; }

/* THE POSITION RULE

   Amber is this page's colour for the figure that moves, and where
   you are in the deck is the one figure here that does. It is a fill
   and never text: #FFBF00 on white does not clear 4.5:1, so the
   count beside it stays ink and the rule carries the colour. */
.td-deck-rail {
  flex: 0 1 clamp(72px, 16vw, 190px);
  height: 2px;
  background: var(--line-strong);
  border-radius: 2px;
  overflow: hidden;
}
.td-deck-rail i {
  display: block;
  height: 100%;
  background: var(--accent-fill);
  border-radius: 2px;
  transition: transform .5s cubic-bezier(.22, .61, .36, 1);
}
/* a hairline between the name and the count, so an image called
   "Bangla Road 1" does not run into "3 / 6" as one string */
.td-deck-sep {
  width: 1px;
  align-self: center;
  height: 11px;
  background: var(--line-strong);
}

/* ------------------------------------------------------------
   THE VIEWER — a native dialog, so Escape, the backdrop and the
   focus trap are the browser's job rather than ours
   ------------------------------------------------------------ */
.td-lb {
  width: min(1240px, 94vw);
  max-width: none;
  max-height: 94vh;
  padding: 0;
  border: 0;
  background: none;
  color: var(--on-navy);
  overflow: visible;
}
.td-lb::backdrop {
  background: rgba(0, 6, 46, .88);
  backdrop-filter: blur(7px);
}
.td-lb-in { position: relative; }
.td-lb img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 80vh;
  object-fit: contain;
  border-radius: var(--r);
  background: var(--navy-deep);
}
.td-lb-cap {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: .85rem;
  margin-top: .9rem;
  font-family: var(--f-mono);
  font-size: 11.5px;
  letter-spacing: .06em;
  color: var(--on-navy);
}
.td-lb-cap .num { color: var(--on-navy-dim); }
.td-lb-cap .td-deck-sep { background: rgba(221, 225, 247, .35); }
.td-lb-in:focus { outline: none; }

.td-lb-btn {
  position: absolute;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 44px clears the touch-target floor without a hit-area hack */
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid rgba(221, 225, 247, .30);
  border-radius: var(--r);
  background: rgba(0, 6, 46, .62);
  color: var(--on-navy);
  cursor: pointer;
  transition: color .18s ease, border-color .18s ease, background-color .18s ease;
}
.td-lb-btn svg { width: 19px; height: 19px; }
.td-lb-btn:hover { background: rgba(221, 225, 247, .14); border-color: var(--on-navy); }
.td-lb-btn[disabled] { opacity: .35; cursor: default; }
.td-lb-btn[disabled]:hover { background: rgba(0, 6, 46, .62); border-color: rgba(221, 225, 247, .30); }

.td-lb-x    { top: -3.4rem; right: 0; }
.td-lb-prev { top: 50%; left: 1rem;  transform: translateY(-50%); }
.td-lb-next { top: 50%; right: 1rem; transform: translateY(-50%); }

@media (max-width: 700px) {
  /* 66vw, not the 74 this was: a 50-degree turn foreshortens a
     neighbour to well under half its width, and at 74vw the pair of
     them had about 20px of a 390px screen each to appear in -- the
     deck read as one photograph with something behind it. The hero
     gives up a little width so the deck still reads as a deck. The
     fade comes in tighter here because there is less room either side
     of the centre frame to spend on it. */
  .td-gal.is-deck {
    --cw: clamp(190px, 66vw, 300px);
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
  }
  .td-lb { width: 96vw; }
  .td-lb-prev { left: .5rem; }
  .td-lb-next { right: .5rem; }
  .td-lb-x { top: -3.1rem; }
}

@media (prefers-reduced-motion: reduce) {
  /* no fan, no travel: the deck lies flat and the frames simply
     change. The grade stays -- brightness, saturation and focus are
     not motion, and they are what says which frame is the subject. */
  .td-gal.is-deck > li,
  .td-gal.is-deck .td-frame,
  .td-gal.is-deck figure::before,
  .td-gal.is-deck figure::after,
  .td-deck-rail i { transition-duration: .01ms; }
  .td-gal.is-deck [data-active] .td-frame:hover,
  .td-gal.is-deck [data-active] .td-frame:active { transform: none; }
  .td-gal-btn:active { transform: none; }
}

/* ------------------------------------------------------------
   THE CLOSE

   This was a full-bleed navy field, which put two near-blacks against
   each other where it met the footer. It now makes the same move the
   home page makes: the page's last section is its brightest surface,
   so the footer's solid #000 reads as a deliberate close rather than
   the band dissolving into it.

   The container has no fill of its own -- the page ground shows
   through it. A hairline and the house radius are the whole thing,
   and the amber button is the only filled object left down here.
   ------------------------------------------------------------ */
.tt-band,
.td-band {
  background: none;
  border: 0;
  color: var(--body);
  /* the room under the card is what keeps the ground, not the card,
     against the footer */
  padding: clamp(1.25rem, 2.6vw, 2.25rem) 0 clamp(3.5rem, 6vw, 5rem);
}

/* the band ran wider than the page grid to give the home page's map
   room to breathe. This one pulls in well inside it: a closing card is
   one last thing to read, not another full-width section, and the
   ground either side of it is what makes it read as a card at all. */
.tt-band .wrap,
.td-band .wrap { width: min(880px, 100% - 3rem); }

.tt-band-in,
.td-band-in {
  /* less top and bottom than side: the card holds two short lines and
     a pair of buttons, and square padding left it standing taller than
     it has anything to say */
  padding: clamp(1.35rem, 2.1vw, 1.75rem) clamp(1.75rem, 3vw, 2.6rem);
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
}

.tt-band-in h2,
.td-band-in h2 { color: var(--ink); }

.tt-band-in p,
.td-band-in p { color: var(--body); }

@media (max-width: 760px) {
  /* the stacked rule above this zeroes the side padding, which a framed
     card cannot do */
  .tt-band-in,
  .td-band-in { padding: clamp(1.4rem, 5vw, 1.9rem); }
}
