/* City of London off-site hotel comparison.
   Lifted verbatim from design/hotels.original.html. The only additions are marked
   "ADDED:" — a button reset (the refresh control became a real <button>), a dark-mode
   button colour token, and loading / error / sold-out states. Light mode renders
   byte-identically to the original design. */

:root {
  --paper: #eaeef1;
  --card: #ffffff;
  --card-2: #f4f6f8;
  --ink: #171c22;
  --ink-soft: #47535f;
  --ink-faint: #6c7884;
  --line: #d6dde3;
  --line-soft: #e4e9ee;
  --accent: #0f5560;      /* deep Thames teal */
  --accent-soft: #e0edee;
  --brass: #a9772b;       /* City brass, used sparingly */
  --good: #2f7d5b;
  --good-soft: #e6f2ec;   /* ADDED: cheaper-elsewhere pill */
  --out: #9a3128;         /* ADDED: sold-out marker */
  --out-soft: #fbe9e7;
  --bar: #7fb3bb;
  --bar-track: #dde4e8;
  --btn: #0f5560;         /* ADDED: was hardcoded on .refresh-btn */
  --shadow: 0 1px 2px rgba(20,30,40,.06), 0 6px 20px rgba(20,30,40,.05);
  --radius: 12px;
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", "Roboto Mono", Menlo, Consolas, monospace;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #0d1115;
    --card: #161c22;
    --card-2: #1b232b;
    --ink: #e9edf0;
    --ink-soft: #aab5bf;
    --ink-faint: #7d8892;
    --line: #28323b;
    --line-soft: #212a32;
    --accent: #4aa3ad;
    --accent-soft: #16302f;
    --brass: #d0a250;
    --good: #5cbf8f;
    --good-soft: #14312a;   /* ADDED: cheaper-elsewhere pill */
    --out: #f08b7f;         /* ADDED: sold-out marker */
    --out-soft: #3a1f1c;
    --bar: #3c8c96;
    --bar-track: #232d35;
    --btn: #2c7a84;       /* ADDED: keeps white button text legible in dark mode */
    --shadow: 0 1px 2px rgba(0,0,0,.3), 0 8px 24px rgba(0,0,0,.28);
  }
}
:root[data-theme="light"] {
  --paper: #eaeef1; --card: #ffffff; --card-2: #f4f6f8; --ink: #171c22;
  --ink-soft: #47535f; --ink-faint: #6c7884; --line: #d6dde3; --line-soft: #e4e9ee;
  --accent: #0f5560; --accent-soft: #e0edee; --brass: #a9772b; --good: #2f7d5b;
  --bar: #7fb3bb; --bar-track: #dde4e8; --btn: #0f5560;
  --good-soft: #e6f2ec; --out: #9a3128; --out-soft: #fbe9e7;
  --shadow: 0 1px 2px rgba(20,30,40,.06), 0 6px 20px rgba(20,30,40,.05);
}
:root[data-theme="dark"] {
  --paper: #0d1115; --card: #161c22; --card-2: #1b232b; --ink: #e9edf0;
  --ink-soft: #aab5bf; --ink-faint: #7d8892; --line: #28323b; --line-soft: #212a32;
  --accent: #4aa3ad; --accent-soft: #16302f; --brass: #d0a250; --good: #5cbf8f;
  --bar: #3c8c96; --bar-track: #232d35; --btn: #2c7a84;
  --good-soft: #14312a; --out: #f08b7f; --out-soft: #3a1f1c;
  --shadow: 0 1px 2px rgba(0,0,0,.3), 0 8px 24px rgba(0,0,0,.28);
}

* { box-sizing: border-box; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
.wrap { max-width: 940px; margin: 0 auto; padding: 32px 20px 64px; }

/* ---- Header ---- */
header { margin-bottom: 26px; }
.eyebrow {
  font-family: var(--mono);
  font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--accent); margin: 0 0 10px;
}
h1 {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(28px, 5vw, 40px);
  line-height: 1.08;
  letter-spacing: -.01em;
  text-wrap: balance;
  margin: 0 0 14px;
}
.lede { color: var(--ink-soft); font-size: 16px; max-width: 62ch; margin: 0; }

/* ---- Header top row + status card ---- */
.head-top {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 20px 30px; flex-wrap: wrap;
}
.head-left { flex: 1 1 58%; min-width: 300px; }
.status {
  flex: 0 0 auto; min-width: 208px;
  display: flex; flex-direction: column; gap: 11px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 14px 16px;
}
.status .st-label {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-faint); margin: 0 0 4px;
}
.status .refresh-val {
  display: flex; align-items: center; gap: 8px; margin: 0;
  font-size: 14px; font-weight: 600; color: var(--ink);
}
.status .dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--good);
  box-shadow: 0 0 0 3px rgba(46,160,110,.28); flex: none;
}
.status hr { border: 0; border-top: 1px solid var(--line-soft); margin: 1px 0; }
.status .updated-val {
  font-family: var(--serif); font-weight: 600; font-size: 23px;
  line-height: 1.08; color: var(--accent); margin: 0;
}
.status .updated-utc {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 12.5px; letter-spacing: .02em; color: var(--ink-faint); margin: 4px 0 0;
}
.status .refresh-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  margin-top: 3px; padding: 9px 12px; border-radius: 9px;
  background: var(--btn); color: #ffffff; text-decoration: none;
  font-size: 13px; font-weight: 600; letter-spacing: .01em;
  border: 1px solid transparent; cursor: pointer;
  transition: filter .15s ease;
  font-family: inherit;     /* ADDED: <button> does not inherit body font */
  width: 100%;              /* ADDED: <button> does not stretch like the old <a> */
  -webkit-appearance: none; /* ADDED: strip iOS button chrome */
  appearance: none;
}
.status .refresh-btn:hover { filter: brightness(1.12); }
.status .refresh-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.status .refresh-btn .ico { font-size: 15px; line-height: 1; }
.status .refresh-btn .ext { font-size: 12px; opacity: .8; }
/* ADDED: disabled/in-flight state for the refresh button */
.status .refresh-btn[disabled] { opacity: .62; cursor: progress; filter: none; }
@media (prefers-reduced-motion: no-preference) {
  .status .refresh-btn.busy .ico { animation: spin .9s linear infinite; }
  @keyframes spin { to { transform: rotate(360deg); } }
}
/* ADDED: link to live prices, demoted below the real refresh button */
.status .live-link {
  font-size: 12px; color: var(--ink-faint); text-align: center;
  text-decoration: none; margin-top: -3px;
}
.status .live-link:hover { color: var(--accent); text-decoration: underline; }

@media (max-width: 560px) {
  .status { width: 100%; min-width: 0; }
}
@media (prefers-reduced-motion: no-preference) {
  .status .dot { animation: pulse 2.6s ease-in-out infinite; }
  @keyframes pulse {
    0%, 100% { box-shadow: 0 0 0 3px rgba(46,160,110,.30); }
    50%      { box-shadow: 0 0 0 7px rgba(46,160,110,0); }
  }
}
/* ADDED: dot turns amber while data is stale, red if the fetch failed */
.status .dot.stale { background: var(--brass); box-shadow: 0 0 0 3px rgba(169,119,43,.28); animation: none; }
.status .dot.error { background: #c0483c; box-shadow: 0 0 0 3px rgba(192,72,60,.28); animation: none; }

.meta {
  display: flex; flex-wrap: wrap; gap: 10px 22px;
  margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--line);
}
.meta div { display: flex; flex-direction: column; gap: 2px; }
.meta dt {
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-faint);
}
.meta dd { margin: 0; font-size: 14px; font-weight: 600; color: var(--ink); }

/* ---- Callout ---- */
.callout {
  display: flex; gap: 12px; align-items: flex-start;
  background: var(--card-2); border: 1px solid var(--line);
  border-left: 3px solid var(--brass);
  border-radius: 10px; padding: 14px 16px; margin: 24px 0 8px;
}
.callout .k {
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--brass); font-weight: 700;
  white-space: nowrap; padding-top: 1px;
}
.callout p { margin: 0; font-size: 14px; color: var(--ink-soft); }
.callout strong { color: var(--ink); }

/* ---- Legend ---- */
.legend {
  display: flex; flex-wrap: wrap; gap: 8px 18px;
  font-size: 12.5px; color: var(--ink-faint);
  margin: 26px 0 14px;
}
.legend b { color: var(--ink-soft); font-weight: 600; }

/* ---- Sort & filter bar ---- */
.controls {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 16px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 12px 16px; margin: 0 0 14px;
}
.ctl { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ctl > label, .count {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-faint); font-weight: 600;
}
.ctl select {
  font: inherit; font-size: 13.5px; color: var(--ink);
  background: var(--card-2); border: 1px solid var(--line);
  border-radius: 8px; padding: 6px 10px; min-height: 34px;
}
.ctl select:disabled { color: var(--ink-faint); opacity: .7; }
.ctl select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.ctl.checks { flex-direction: row; flex-wrap: wrap; gap: 6px 14px; padding-bottom: 7px; }
.chk {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; color: var(--ink-soft); cursor: pointer; white-space: nowrap;
}
.chk input { accent-color: var(--accent); width: 15px; height: 15px; margin: 0; }
.ctl-end {
  margin-left: auto; display: flex; align-items: center; gap: 12px;
  padding-bottom: 8px;
}
.count { margin: 0; white-space: nowrap; }
/* ADDED: names what "Recommended" actually weighs, only while that sort is on */
.sort-hint {
  flex: 1 1 100%; margin: 0; padding-top: 9px;
  border-top: 1px solid var(--line-soft);
  font-size: 12.5px; color: var(--ink-faint);
}
.reset, .linkish {
  font: inherit; font-size: 12.5px; font-weight: 600; color: var(--accent);
  background: transparent; border: 1px solid var(--line);
  border-radius: 999px; padding: 4px 12px; cursor: pointer;
}
.linkish { border: 0; padding: 0; text-decoration: underline; }
.reset:hover { border-color: var(--accent); }

@media (max-width: 620px) {
  .controls { gap: 10px 12px; }
  .ctl { flex: 1 1 44%; }
  .ctl select { width: 100%; }
  .ctl.checks, .ctl-end { flex: 1 1 100%; margin-left: 0; }
}

/* ---- List ---- */
.list { display: flex; flex-direction: column; gap: 12px; }
.row {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px 18px;
  display: grid;
  grid-template-columns: 30px 1fr auto;
  grid-template-areas:
    "rank name price"
    "rank book book"
    "rank bar  bar";
  gap: 6px 14px;
  align-items: start;
}
.row.pick { border-color: var(--accent); }
.rank {
  grid-area: rank;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 13px; color: var(--ink-faint); font-weight: 600;
  padding-top: 3px;
}
.name { grid-area: name; min-width: 0; }
.name h3 {
  font-family: var(--serif); font-weight: 600;
  font-size: 19px; margin: 0 0 5px; line-height: 1.2;
}
.tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.tag {
  font-size: 11.5px; font-weight: 600; letter-spacing: .01em;
  padding: 2px 8px; border-radius: 999px;
  background: var(--card-2); color: var(--ink-soft);
  border: 1px solid var(--line-soft); white-space: nowrap;
}
.tag.chain { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
.tag.closest { background: transparent; color: var(--brass); border-color: var(--brass); }
/* ADDED: marks a property the scraper discovered, i.e. not on the original shortlist */
.tag.new { background: transparent; color: var(--good); border-color: var(--good); }
/* ADDED: unmistakable marker for a property with no rooms on these dates */
.tag.out {
  background: var(--out-soft); color: var(--out);
  border-color: transparent; text-transform: uppercase;
  font-size: 10.5px; letter-spacing: .06em;
}
.tag.flex { background: transparent; color: var(--good); border-color: var(--line); }
.note { font-size: 13.5px; color: var(--ink-soft); margin: 2px 0 0; }

/* ADDED: Google guest score, distinct from the star classification */
.score { display: flex; align-items: baseline; gap: 5px; margin: 0 0 7px; }
.sc-val {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 13.5px; font-weight: 700; color: var(--brass);
}
.sc-of { font-size: 11.5px; color: var(--ink-faint); }
.sc-n { font-size: 11.5px; color: var(--ink-faint); }
.sc-n::before { content: "· "; }
/* ADDED: a score off too few reviews is shown but flagged, and never sorted on */
.sc-thin {
  font-size: 10.5px; font-weight: 600; letter-spacing: .02em;
  color: var(--ink-faint); border: 1px dashed var(--line);
  border-radius: 999px; padding: 0 7px; cursor: help;
}

/* ADDED: booking links, plus the cheaper-elsewhere callout.
   Sits on its own row, pushed to the right edge of the card so the links read
   as actions on the whole property rather than part of the description. */
.book {
  grid-area: book;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end;
  gap: 6px 14px; margin: 8px 0 0; font-size: 13px;
}
.book a { color: var(--accent); font-weight: 600; text-decoration: none; }
.book a:hover { text-decoration: underline; }
.book .save {
  font-family: var(--mono); font-size: 11.5px; font-weight: 600;
  color: var(--good); background: var(--good-soft);
  border-radius: 999px; padding: 2px 9px;
}

.price { grid-area: price; text-align: right; white-space: nowrap; }
.total {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 21px; font-weight: 700; color: var(--ink); line-height: 1;
}
.total .cur { font-size: 13px; color: var(--ink-faint); font-weight: 600; }
.per {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 12px; color: var(--ink-faint); margin-top: 5px;
}
/* ADDED: walk time sized up — how far it is matters as much as what it costs,
   so it reads at a glance instead of as fine print under the nightly rate. */
.walk { font-size: 14px; color: var(--ink-soft); margin-top: 7px; }
.walk b { color: var(--ink); font-weight: 700; font-size: 16px; }

.barwrap { grid-area: bar; margin-top: 6px; }
.track { height: 5px; border-radius: 4px; background: var(--bar-track); overflow: hidden; }
.fill { height: 100%; background: var(--bar); border-radius: 4px; }

/* ADDED: sold-out / no-price rows are dimmed and sink to the bottom of the list */
.row.sold-out { opacity: .72; }
.row.sold-out .total { color: var(--ink-faint); }

/* ---- Recommend ---- */
.rec {
  margin-top: 30px; background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 20px 20px 8px; box-shadow: var(--shadow);
}
.rec h2, .foot h2 {
  font-family: var(--serif); font-size: 18px; font-weight: 600; margin: 0 0 4px;
}
.rec > p { color: var(--ink-faint); font-size: 13px; margin: 0 0 14px; }
.rec ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.rec li {
  display: grid; grid-template-columns: 1fr auto; gap: 4px 14px;
  padding-bottom: 12px; border-bottom: 1px solid var(--line-soft);
}
.rec li:last-child { border-bottom: 0; }
.rec .why { font-family: var(--mono); font-size: 11px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--accent); grid-column: 1 / -1; }
.rec .what { font-weight: 600; font-size: 15px; }
.rec .sub { font-size: 13px; color: var(--ink-soft); grid-column: 1 / -1; }
.rec .amt { font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-weight: 700; text-align: right; align-self: center; }

/* ---- Footer ---- */
.foot { margin-top: 30px; padding-top: 18px; border-top: 1px solid var(--line); }
.foot p { font-size: 12.5px; color: var(--ink-faint); max-width: 70ch; margin: 0 0 8px; }
.foot a { color: var(--accent); }

/* ADDED: first-paint and failure states for the data-driven list */
.state {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 22px 18px; text-align: center;
  color: var(--ink-soft); font-size: 14px;
}
.state.error { border-left: 3px solid var(--brass); text-align: left; }
.state code {
  font-family: var(--mono); font-size: 12.5px; background: var(--card-2);
  padding: 1px 5px; border-radius: 4px;
}
.skeleton { height: 92px; background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow); }
@media (prefers-reduced-motion: no-preference) {
  .skeleton { animation: fade 1.5s ease-in-out infinite; }
  @keyframes fade { 0%,100% { opacity: .55; } 50% { opacity: .95; } }
}

@media (max-width: 560px) {
  .row {
    grid-template-columns: 26px 1fr;
    grid-template-areas:
      "rank name"
      "rank price"
      "rank book"
      "rank bar";
  }
  .price { text-align: left; margin-top: 4px; }
  /* Right-aligning in a narrow column just strands the links, so let them
     line up with the name and price instead. */
  .book { justify-content: flex-start; }
  .total { font-size: 19px; }
}
@media print {
  body { background: #fff; }
  .row, .rec { box-shadow: none; }
  .status .refresh-btn, .status .live-link { display: none; }
}
@media (prefers-reduced-motion: no-preference) {
  .fill { transition: width .6s cubic-bezier(.4,0,.2,1); }
}
