/* ============================================================================
   portal.css — patterns adapted from the Tanzania Tourist Board portal
   (destinationtanzania.tz).

   That site is a national marketplace, not an operator site, so most of its
   surface (business lounge, operator matching, supply registration, accounts)
   does not apply here. What transfers is the traveller-facing vocabulary:
   "Best time to visit", "Things to do", a wishlist, a currency selector, and
   a review summary with distribution bars.

   Each is re-cut for a single operator, and each carries an access angle the
   original does not have.
   ========================================================================= */

/* ========================================================= SEASON TABLE ==
   Twelve months down the page rather than across, so every row can carry
   four different kinds of advice without being squeezed into a cell three
   words wide. */
.season-scroll {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  background: var(--surface-1);
  scrollbar-gutter: stable;
}
.season-scroll:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

table.season {
  inline-size: 100%;
  border-collapse: collapse;
  min-inline-size: 50rem;
  font-size: var(--t-sm);
}
.season caption {
  caption-side: top;
  text-align: left;
  padding: var(--sp-m) var(--sp-m) 0;
  color: var(--text-2);
  font-size: var(--t-sm);
}
.season th,
.season td {
  padding: 0.8rem 1rem;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--line);
}
.season thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface-2);
  font-size: var(--t-xs);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--text-2);
  font-weight: 750;
}
.season tbody th { font-weight: 750; color: var(--text-1); white-space: nowrap; }
.season tbody tr:hover { background: var(--surface-2); }
.season tbody tr:last-child :is(th, td) { border-bottom: 0; }

/* A season rating is never colour alone: each carries a glyph and a word. */
.rate {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-weight: 700;
  white-space: nowrap;
}
.rate svg { inline-size: 1em; block-size: 1em; flex: none; }
.rate[data-r='best'] { color: var(--accent); }
.rate[data-r='good'] { color: var(--gold); }
.rate[data-r='hard'] { color: var(--text-3); }

/* ========================================================== THINGS TO DO ==
   Photo tiles with the label over the image and the access note beneath,
   because the access note is the part people came for. */
.todo {
  display: grid;
  gap: var(--sp-m);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
}
.todo-item {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  overflow: hidden;
  background: var(--surface-1);
  transition: box-shadow var(--d-base) var(--e-out),
              translate var(--d-base) var(--e-out),
              border-color var(--d-base) var(--e-soft);
}
.todo-item:hover { box-shadow: var(--shadow-3); translate: 0 -4px; border-color: transparent; }
.todo-media { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--surface-2); }
.todo-media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transition: scale var(--d-epic) var(--e-out);
}
.todo-item:hover .todo-media img { scale: 1.07; }
.todo-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgb(10 14 18 / 8%) 42%, rgb(10 14 18 / 74%) 100%);
}
.todo-label { position: absolute; inset: auto var(--sp-s) var(--sp-s) var(--sp-s); z-index: 2; color: #fff; }
.todo-label h3 { font-size: var(--t-base); font-weight: 750; color: #fff; text-shadow: 0 1px 10px rgb(0 0 0 / 65%); }
.todo-label p { font-size: var(--t-xs); color: #e6e2da; text-shadow: 0 1px 8px rgb(0 0 0 / 70%); }
.todo-body { padding: var(--sp-s) var(--sp-m) var(--sp-m); display: grid; gap: 0.5rem; }
.todo-body > p { font-size: var(--t-sm); color: var(--text-2); line-height: 1.55; }

/* ================================================================ SAVE ==
   A bookmark toggle on every trip card. State lives in localStorage, which
   is per-device and never reaches us, so the wording says "on this device"
   rather than implying an account exists. */
.save-btn {
  position: absolute;
  /* Top-RIGHT, not top-left. On the left it sat on top of .tour-over and hid
     the first word of every card title — "The Level Horizon" read as "Level
     Horizon", "Two Names, One Booking" as "Names, One Booking". Top-right is
     also where a save control is conventionally looked for, and it is the one
     corner of the card that was free. */
  inset: 0.6rem 0.6rem auto auto;
  z-index: 4;
  display: grid;
  place-items: center;
  inline-size: 38px;
  block-size: 38px;
  border-radius: 50%;
  border: 1px solid rgb(255 255 255 / 55%);
  background: rgb(20 24 28 / 48%);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: #fff;
  cursor: pointer;
  transition: background-color var(--d-fast) var(--e-soft),
              color var(--d-fast) var(--e-soft),
              scale var(--d-fast) var(--e-spring);
}
.save-btn:hover { scale: 1.1; background: rgb(20 24 28 / 74%); }
.save-btn svg { inline-size: 19px; block-size: 19px; }
.save-btn .ico-saved { display: none; }
.save-btn[aria-pressed='true'] { background: #fff; border-color: #fff; color: var(--accent); }
.save-btn[aria-pressed='true'] .ico-save { display: none; }
.save-btn[aria-pressed='true'] .ico-saved { display: block; }

/* the running count in the utility bar */
.saved-count { display: inline-flex; align-items: center; gap: 0.35rem; font-weight: 700; color: var(--accent); }
.saved-count svg { inline-size: 0.95rem; block-size: 0.95rem; }
.saved-count[hidden] { display: none; }

/* ============================================================ CURRENCY ==
   A working selector in the utility bar. Rates are fixed and illustrative,
   and every converted figure says so. */
.cur-select {
  appearance: none;
  border: 1px solid transparent;
  background-color: transparent;
  font: inherit;
  color: var(--text-2);
  padding: 0.2rem 1.35rem 0.2rem 0.4rem;
  border-radius: var(--r-s);
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23646464' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.25rem center;
  background-size: 0.85rem;
}
.cur-select:hover { color: var(--text-1); background-color: var(--surface-3); }
.cur-select:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.price .cur-note { display: block; font-size: 0.68rem; color: var(--text-3); line-height: 1.35; }

/* ====================================================== REVIEW SUMMARY ==
   Average, count, and a distribution bar per star level. */
.rev-summary {
  display: grid;
  gap: var(--sp-l);
  align-items: center;
  padding: var(--sp-l);
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  background: var(--surface-1);
  margin-bottom: var(--sp-l);
}
@media (width >= 48rem) { .rev-summary { grid-template-columns: auto minmax(0, 1fr); } }
.rev-score { text-align: center; }
.rev-score b {
  display: block;
  font-size: var(--t-3xl);
  font-weight: 800;
  line-height: 1;
  color: var(--text-1);
  font-variant-numeric: lining-nums tabular-nums;
}
.rev-score .stars { justify-content: center; margin: 0.4rem 0 0.25rem; }
.rev-score > span { font-size: var(--t-xs); color: var(--text-3); }
.rev-bars { display: grid; gap: 0.35rem; }
.rev-bar {
  display: grid;
  grid-template-columns: 3.6rem 1fr 2.8rem;
  gap: 0.6rem;
  align-items: center;
  font-size: var(--t-xs);
  color: var(--text-3);
}
.rev-bar i { display: block; block-size: 8px; border-radius: 4px; background: var(--surface-3); overflow: hidden; }
.rev-bar i::after {
  content: '';
  display: block;
  block-size: 100%;
  inline-size: var(--pct, 0%);
  border-radius: 4px;
  background: var(--star);
}

/* ============================================================ FEE LIST ==== */
.fees { display: grid; gap: 0.6rem; }
.fee {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem var(--sp-s);
  align-items: baseline;
  justify-content: space-between;
  padding: 0.85rem var(--sp-m);
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  background: var(--surface-1);
}
.fee b { font-size: var(--t-sm); font-weight: 750; }
.fee > span { font-size: var(--t-sm); color: var(--text-2); }
.fee .fee-amt { font-weight: 750; color: var(--text-1); white-space: nowrap; }


/* ===================================================== JS-ONLY CONTROLS ==
   Saving and currency conversion are entirely client-side. Without
   JavaScript they would be dead controls, and a dead control is worse than
   an absent one — so they are only revealed once boot.js has set .js on
   <html>. Prices then simply stay in their published currency.

   The same applies in print: neither control means anything on paper. */
.save-btn,
.cur-select,
.saved-count,
[data-saved-filter] { display: none; }

.js .save-btn { display: grid; }
.js .cur-select { display: inline-block; }
.js .saved-count { display: inline-flex; }
.js [data-saved-filter] { display: inline-flex; }
.js .saved-count[hidden] { display: none; }

@media print {
  .save-btn,
  .cur-select,
  .saved-count,
  [data-saved-filter] { display: none !important; }
}
