
@font-face { font-family: "Anton Local"; src: url("/brand/Anton-Regular.ttf") format("truetype"); font-display: swap; }
@font-face { font-family: "Archivo Local"; src: url("/brand/Archivo-wdth-wght.ttf") format("truetype"); font-weight: 100 900; font-stretch: 62% 125%; font-display: swap; }
/* App-like, light and dense, now using the Burlington on a Budget identity. */
:root {
  --brand: #FF6B35;
  --brand-ink: #0B3954;
  --brand-wash: #FDF6EC;
  --app-bg: #FDF6EC;
  --surface: #FFFCF7;
  --ink: #0B3954;
  --muted: #8A8378;
  --faint: #A9A196;
  --line: #E7DCCE;
  --hair: #F4EADF;
  --slate: #31566B;
  --event-wash: #EAF2F6;
  --event-ink: #0B3954;
  --mark: #FFE1D5;
  --chev: #B8AEA1;
  color-scheme: light;
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--app-bg);
  color: var(--ink);
  font-family: 'Archivo Local', system-ui, -apple-system, 'Segoe UI', Roboto,
    'Helvetica Neue', Arial, sans-serif;
  font-size: 15px;
  line-height: 1.45;
  /* Room for the fixed tab bar, plus the iOS home indicator. */
  padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px));
}
a { color: inherit; text-decoration: none; }
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible,
select:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; }
.wrap { max-width: 1120px; margin: 0 auto; padding: 0 16px; }
@media (min-width: 900px) { .wrap { padding: 0 48px; } }

/* --- header ------------------------------------------------------------- */
.top { background: var(--surface); border-bottom: 1px solid var(--line); }
.top .wrap { padding-top: 14px; padding-bottom: 12px; }
.brandrow { display: flex; align-items: center; gap: 8px; }
.brandlock { display: flex; align-items: center; flex: none; }
/* The tagline lockup is wider than the old compact signature (540x112 design box), so
   the height gives a little back -- 46px at a 4.82 aspect keeps the header from pushing
   the Burlington, ON chip off a 360px phone. */
.brandwordmark { width: 222px; height: 46px; object-fit: contain; }
.place { margin-left: auto; font-size: 11.5px; color: var(--muted); font-weight: 600; }
.desknav { display: none; }
@media (min-width: 900px) {
  .brandwordmark { width: 265px; height: 55px; }
  .desknav {
    display: flex; gap: 18px; font-size: 13.5px; font-weight: 600;
    color: var(--slate); margin-left: 24px;
  }
  .desknav a.on { color: var(--brand); font-weight: 700; }
  .place { font-size: 12px; }
}

/* Search-first: the field is the first thing under the wordmark on the home screen. */
.searchform { margin-top: 12px; display: block; }
.searchbox {
  display: flex; align-items: center; gap: 8px;
  background: var(--hair); border: 1.5px solid transparent; border-radius: 12px;
  padding: 9px 14px;
}
.searchbox:focus-within { border-color: var(--brand); background: var(--hair); }
.searchbox .ico { color: var(--muted); font-size: 15px; line-height: 1; }
.searchbox input {
  border: 0; background: none; outline: none; width: 100%;
  font: inherit; font-size: 14px; color: var(--ink); padding: 2px 0;
}
.searchbox input::placeholder { color: var(--faint); }

/* --- day pills ------------------------------------------------------------ */
/* A strip that scrolls sideways is fine under a thumb and hostile under a mouse: a plain
   wheel scrolls the page, not the strip, and hiding the scrollbar removes the last thing
   left to drag. So the strip only scrolls where swiping exists. From 900px up it wraps
   instead, which is also where there is width to wrap into. */
.pills { display: flex; gap: 8px; margin-top: 12px; overflow-x: auto;
  padding-bottom: 6px; scroll-behavior: smooth; scroll-padding-inline: 16px;
  scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
.pills::-webkit-scrollbar { height: 4px; }
.pills::-webkit-scrollbar-track { background: transparent; }
.pills::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }
/* The fade says "there is more this way". A mask on the scroller itself stays pinned to
   its right edge -- it paints in the element's own box, not the scrolled content's -- so
   this needs no wrapper element. `.more` is added by script only while there really is
   something further right, so a fully-scrolled strip is never dimmed for nothing. */
.pills.more-end { mask-image: linear-gradient(to right,
  #000 calc(100% - 30px), transparent); }
.pills.more-start { mask-image: linear-gradient(to right, transparent, #000 30px); }
.pills.more-start.more-end { mask-image: linear-gradient(to right,
  transparent, #000 30px, #000 calc(100% - 30px), transparent); }
@media (min-width: 900px) {
  .pills { flex-wrap: wrap; overflow-x: visible; padding-bottom: 0; }
  .pills.more-start, .pills.more-end { mask-image: none; }
}
@media (prefers-reduced-motion: reduce) { .pills { scroll-behavior: auto; } }
.pill {
  padding: 7px 14px; border-radius: 999px; background: var(--surface);
  border: 1px solid var(--line); font-size: 12.5px; font-weight: 600;
  color: var(--slate); white-space: nowrap; flex: none;
}
.pill.on { background: var(--brand); border-color: var(--brand); color: var(--brand-ink);
  font-weight: 700; }
.pill.dark { background: var(--ink); border-color: var(--ink); color: var(--brand-wash);
  font-weight: 700; }

/* --- section headings ----------------------------------------------------- */
.sechead {
  display: flex; align-items: baseline; justify-content: space-between;
  margin: 16px 2px 8px; gap: 12px;
}
.sechead h2 { font-weight: 800; font-size: 16px; margin: 0; letter-spacing: -0.2px; }
/* `.count`, not `.note`: `.note` is the grey panel further down, and reusing the name
   here gave every section heading's "34 deals" a panel background of its own. */
.sechead .count { font-size: 12px; color: var(--muted); font-weight: 600;
  white-space: nowrap; }
/* The phone's only way to reach events, which fall below the whole deal list once
   `.split` collapses. Hidden from 900px up, where the rail already shows them. */
.jump { color: var(--brand); font-weight: 700; }
@media (min-width: 900px) { .jump { display: none; } }
/* `.always` is for a section that is below the list at EVERY width -- the daytime half
   of the day page is in the same column as the evening half, so a desktop reader is
   scrolling past a couple of hundred rows to reach it just as a phone reader is. Higher
   specificity than the rule above, so it wins inside the media query without one of its
   own. */
.jump.always { display: inline; }
/* Anchors want a little air above them, or a jump lands with the heading flush against
   the top of the viewport and it reads as though the page scrolled too far. */
#events, #daytime, .daybar[id] { scroll-margin-top: 12px; }
h1.big { font: 24px/1.05 "Anton Local", Impact, sans-serif; letter-spacing: .01em; margin: 0; }
@media (min-width: 900px) { h1.big { font-size: 30px; letter-spacing: -0.5px; } }

/* --- the dense list ------------------------------------------------------- */
.list {
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  overflow: hidden;
}
.row {
  display: flex; align-items: center; gap: 12px; padding: 13px 14px;
  border-bottom: 1px solid var(--hair);
}
.row:last-child { border-bottom: 0; }
.row .body { min-width: 0; }
.row .name { font-weight: 700; font-size: 14px; }
.row .sub { font-size: 11.5px; color: var(--muted); }
.row .chev { margin-left: auto; color: var(--chev); flex: none; }
.daybar {
  padding: 9px 14px; background: var(--app-bg); font-size: 10.5px; font-weight: 800;
  letter-spacing: .06em; color: var(--muted); border-bottom: 1px solid var(--hair);
}
.daybar.now { color: var(--brand); }
/* The any-day bar: the group that is not a weekday. Tinted rather than orange-on-cream,
   because orange is the TONIGHT marker and "on every night anyway" is the opposite of
   the claim that marker makes. */
.daybar.any { background: var(--brand-wash); color: var(--brand-ink); }
.daybar .anynote {
  margin-left: 8px; font-size: 10px; font-weight: 700; letter-spacing: 0;
  color: var(--brand);
}

/* The price pill is a FIXED column, and the reason is the scan.

   It used to size to its content so a venue's own phrasing -- "2 for 1", "$0.89/wing" --
   could stretch it. The cost was that every title started at a different x, so a list
   whose whole job is being scanned down had no line to scan down. And the escape hatch
   was worse than the problem: `max-width: 52%` plus an ellipsis meant that on exactly
   the long phrases the rule existed to protect, the PRICE got truncated -- "1/2 price
   wine, $9 ma...". Truncating the one number the reader came for is the worst trade in
   the row.

   So: one width, and long phrasing WRAPS instead of being cut. A three-line pill on a
   badly-phrased price is honest and it is visible, which is how those get noticed and
   fixed at the source. `.event-row` next door has always used a fixed left column for
   its date; this only makes deals agree with it. */
.price {
  background: var(--brand-wash); color: var(--brand-ink); font-weight: 800;
  font-size: 13.5px; line-height: 1.25; padding: 6px 8px; border-radius: 9px;
  flex: none; width: 104px; box-sizing: border-box; text-align: center;
  overflow-wrap: break-word; hyphens: none;
}
/* Same column width as `.price`, so a mixed list keeps one scan line whether the row is
   a deal or an event. */
.tag {
  background: var(--event-wash); color: var(--event-ink); font-weight: 800;
  font-size: 11px; letter-spacing: .05em; padding: 6px 8px; border-radius: 9px;
  white-space: nowrap; flex: none; width: 104px; box-sizing: border-box;
  text-align: center;
}
.event-row {
  display: grid; grid-template-columns: 78px minmax(0, 1fr); gap: 12px;
  padding: 14px; border-bottom: 1px solid var(--hair);
}
.event-row:last-child { border-bottom: 0; }
.event-date {
  color: var(--brand-ink); font-size: 11px; font-weight: 800; line-height: 1.3;
  text-transform: uppercase; letter-spacing: .035em;
}
.event-row .name { font-size: 14px; font-weight: 800; }
.event-row .venue { color: var(--muted); font-size: 11.5px; margin-top: 2px; }
.event-meta { display: flex; flex-wrap: wrap; gap: 7px 12px; margin-top: 7px; }
.event-kind { color: var(--slate); font-size: 10.5px; font-weight: 800;
  text-transform: uppercase; letter-spacing: .045em; }
.evidence { color: var(--brand); font-size: 11px; font-weight: 700; }
/* Quiet, not orange. Nearly every published row is verified -- that is the point of the
   gate -- so a badge on all of them carries no information, and painting it in the
   accent spent the one colour that means "now, act here" on the least surprising fact in
   the row. It stays visible because the claim matters; it stops shouting because it is
   the norm. The colour that has to survive is `.cond`, which marks the rows where the
   deal does NOT simply apply. */
.verified { color: var(--muted); font-weight: 600; }
/* A condition is amber, never orange: orange is the verified tick's colour and this is the
   qualification ON that claim, not another instance of it. */
.cond { color: #B45309; font-weight: 700; }
.condband {
  margin-top: 12px; background: #FFFBEB; border: 1px solid #FDE68A; color: #92400E;
  border-radius: 10px; padding: 9px 12px; font-size: 12.5px; font-weight: 700;
}
/* A collapsed chain row: the link, then a disclosure BESIDE it (never inside -- nesting
   interactive content inside an <a> is invalid and browsers un-nest it). */
.rowgroup { border-bottom: 1px solid var(--hair); }
.rowgroup:last-child { border-bottom: 0; }
.rowgroup .row { border-bottom: 0; }
.locations { padding: 0 14px 11px 14px; }
.locations summary {
  font-size: 11.5px; font-weight: 700; color: var(--brand); cursor: pointer;
  list-style: none;
}
.locations summary::-webkit-details-marker { display: none; }
.locations summary::before { content: "\25B8  "; }
.locations[open] summary::before { content: "\25BE  "; }
.locations .loc {
  display: block; font-size: 12.5px; color: var(--slate); padding: 5px 0 0 14px;
}
.dist { color: var(--muted); }
.daycell {
  width: 46px; text-align: center; font-size: 11px; font-weight: 800;
  color: var(--muted); flex: none;
}
.daycell.now { color: var(--brand); }
.daycell small { display: block; font-size: 9px; color: var(--faint); font-weight: 700; }

/* --- featured ------------------------------------------------------------- */
.featured {
  background: var(--surface); border: 1.5px solid var(--brand); border-radius: 14px;
  padding: 14px 16px; box-shadow: 0 2px 8px rgba(255,107,53,.10);
}
.featured .flags { display: flex; align-items: center; gap: 6px; }
.flag {
  font-size: 10px; font-weight: 800; letter-spacing: .08em; color: var(--brand);
  background: var(--brand-wash); padding: 3px 8px; border-radius: 6px;
}
.flag.grey { background: none; color: var(--faint); letter-spacing: 0; font-weight: 600;
  font-size: 10.5px; padding: 3px 0; }
.featured .main { display: flex; align-items: center; gap: 10px; margin-top: 9px; }
.featured .price { font-size: 17px; padding: 5px 12px; border-radius: 10px; }

/* --- cards / panels ------------------------------------------------------- */
.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  padding: 14px 16px;
}
.pitch {
  background: var(--ink); color: var(--brand-wash); border-radius: 14px; padding: 16px;
  margin-top: 14px;
}
.pitch h3 { font-weight: 800; font-size: 14.5px; margin: 0; }
.pitch p { font-size: 12px; color: var(--faint); margin: 4px 0 0; line-height: 1.5; }
.pitch .go {
  display: inline-block; margin-top: 10px; background: var(--brand); color: var(--brand-ink);
  font-size: 12px; font-weight: 700; padding: 8px 14px; border-radius: 9px;
}
.note {
  background: var(--hair); border-radius: 14px; padding: 13px 16px; font-size: 12px;
  color: var(--muted); line-height: 1.5;
}
.wash {
  background: var(--brand-wash); border-radius: 10px; padding: 9px 12px;
  font-size: 12px; color: var(--brand-ink); font-weight: 600;
}
.more { text-align: center; padding: 12px 0 4px; font-size: 13px; font-weight: 700;
  color: var(--brand); }
mark { background: var(--mark); color: inherit; border-radius: 3px; padding: 0 2px; }

/* --- category grid -------------------------------------------------------- */
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 12px; }
@media (min-width: 700px) { .grid { grid-template-columns: repeat(4, 1fr); } }
.tile { background: var(--hair); border-radius: 12px; padding: 14px; }
.tile .t { font-weight: 800; font-size: 14.5px; }
.tile .n { font-size: 11.5px; color: var(--muted); font-weight: 600; }
.tile.on { background: var(--brand-wash); }
.tile.on .t { color: var(--brand-ink); }
.tile.on .n { color: var(--brand); }

/* --- buttons and forms ---------------------------------------------------- */
.actions { display: flex; gap: 8px; margin-top: 12px; }
.btn {
  flex: 1; text-align: center; padding: 9px 0; border-radius: 10px;
  border: 1px solid var(--line); background: var(--surface);
  font-size: 12.5px; font-weight: 700; color: var(--ink); cursor: pointer;
  font-family: inherit;
}
.btn.go { background: var(--brand); border-color: var(--brand); color: var(--brand-ink); }
label { display: block; font-size: 12px; font-weight: 700; margin: 12px 0 4px;
  color: var(--slate); }
input[type=text], input[type=email], input[type=url], textarea, select {
  width: 100%; font: inherit; font-size: 14px; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  padding: 10px 12px; outline: none;
}
input:focus, textarea:focus, select:focus { border-color: var(--brand); }
/* AFTER the form rules, and it has to be: the field inside the search pill is an
   `input[type=text]` too, and the generic rule above would otherwise draw a second box
   inside the pill. Same specificity, so source order is what decides. */
.searchbox input[type=text] {
  border: 0; background: none; border-radius: 0; padding: 2px 0;
}
.searchbox input[type=text]:focus { border: 0; }
textarea { min-height: 90px; resize: vertical; }
.err {
  background: #FEF2F2; border: 1px solid #FECACA; color: #991B1B; border-radius: 10px;
  padding: 10px 12px; font-size: 12.5px; font-weight: 600; margin-top: 12px;
}
.hint { font-size: 11.5px; color: var(--muted); margin-top: 4px; }

/* --- bottom tab bar ------------------------------------------------------- */
.tabs {
  position: fixed; left: 0; right: 0; bottom: 0; background: var(--surface);
  border-top: 1px solid var(--line); display: grid; grid-template-columns: repeat(5, 1fr);
  padding: 10px 8px calc(14px + env(safe-area-inset-bottom, 0px)); z-index: 20;
}
.tabs a { text-align: center; color: var(--faint); }
.tabs a.on { color: var(--brand); }
/* Drawn icons, not typographic glyphs. The bar used to spend its five slots on ●, ▦, ♫,
   ◉ and ＋: "Tonight" was a filled circle and "Search" a circled circle, near-identical
   silhouettes at 16px, and neither shape meant its destination. A magnifier for search
   is understood everywhere, and giving that up buys nothing. `currentColor` keeps the
   active tab's orange working from the one rule that already sets it. */
.tabs .gl { display: block; height: 20px; line-height: 0; }
.tabs .gl svg { width: 20px; height: 20px; display: inline-block; vertical-align: top;
  fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round;
  stroke-linejoin: round; }
.tabs a.on .gl svg { stroke-width: 2.2; }
.tabs .lb { font-size: 10.5px; font-weight: 600; margin-top: 3px; }
.tabs a.on .lb { font-weight: 700; }
/* The bottom bar is the phone's navigation. At desktop width the header nav is already
   showing the same destinations, and the mockup's 1280 screen has no tab bar. */
@media (min-width: 900px) {
  .tabs { display: none; }
  body { padding-bottom: 0; }
  /* The search field sits IN the header row at desktop -- 420px, as drawn -- and the day
     pills are forced onto their own line by `flex-basis: 100%` rather than being left to
     wrap on their own, which depends on how wide the pills happen to be. */
  .top .wrap { display: flex; align-items: center; flex-wrap: wrap; column-gap: 24px; }
  .top .wrap > .brandrow { flex: 0 0 auto; }
  .searchform { flex: 1 1 260px; max-width: 420px; margin-top: 0; }
  .pills { flex: 1 0 100%; }
  /* `margin-left: auto` has nothing to push against once the brand row stops being full
     width, so this ends up wedged against the search field. The h1 underneath already
     says Burlington, and the mockup's 1280 header does not carry it either. */
  .place { display: none; }
}

/* The 1280 screen is two columns: the list, and a rail carrying events and the venue
   pitch. Below that width it is one column in source order, which is why events come
   after deals in the markup rather than beside them. */
.split { display: block; }
@media (min-width: 900px) {
  .split { display: grid; grid-template-columns: 2fr 1fr; gap: 24px;
    align-items: start; }
  .split > .rail { position: sticky; top: 16px; }
}

.empty { padding: 28px 4px; color: var(--muted); font-size: 13.5px; line-height: 1.6; }
.empty strong { color: var(--ink); }
.stack { display: flex; flex-direction: column; gap: 10px; }
.mt { margin-top: 14px; }
main { padding-top: 14px; }
footer { color: var(--faint); font-size: 11.5px; padding: 24px 0 8px; line-height: 1.6; }
footer a { color: var(--muted); text-decoration: underline; }
