/* Colour and type come from the marketing site (static-hb), so this page looks
 * like it belongs to HostBarrel. The layout, the tiles, the chips and the cards
 * are unchanged - only the palette, the typefaces and the masthead logo.
 *
 * Light only: there is no prefers-color-scheme block any more. The page used to
 * follow the OS into a dark theme, which made it the only HostBarrel surface
 * that did.
 *
 * Source: src/css/quasar.variables.scss and src/css/app.scss. Two blues, kept
 * apart by role exactly as app.scss documents: $color-2 #0890fb for icons,
 * borders, focus rings and marks, where 3:1 is enough; $color-12 #0670c9
 * wherever a blue *word* sits on white, or white sits on blue, and needs more.
 */
:root {
  --ground: #f2f6fc;       /* derived from $color-6 */
  --surface: #ffffff;      /* $color-11 */
  --surface-2: #e1eaf8;    /* $color-6 */
  --ink: #092a44;          /* $color-4  - headings */
  --ink-2: #333333;        /* $color-0  - body text */
  --ink-3: #595f7c;        /* $color-9  - muted */
  --line: #cfd9e9;         /* derived from $color-10 */
  --navy: #0670c9;         /* $color-12 - links, and fills that carry white text */
  --navy-2: #092a44;       /* $color-4  - the darker step on hover */
  --brand-fill: #0890fb;   /* $color-2  - borders, focus rings, marks */
  --on-navy: #ffffff;
  --shadow: 0 1px 2px rgba(9, 42, 68, 0.06), 0 8px 24px -12px rgba(9, 42, 68, 0.18);
  /* Category tint: each tile and group sets --h (a hue); these two turn it into
     an icon colour and a soft background. Kept as-is - the per-category hues
     are how you tell the tiles apart. */
  --tint-l: 42%; --tint-bg-l: 94%; --tint-bg-s: 70%;

  /* Brand orange. On the marketing site orange means act (.btn-gradient, the
   * footer tagline strip, the navbar support box), so here it takes the two
   * buttons that already existed. The ramp stops at #ff7d13 rather than running
   * on to #ff9b24: white on the light end measures about 2.2:1. Both stops are
   * from .gradien-orange in app.scss. */
  --cta: linear-gradient(90deg, #ff5910 0%, #ff7d13 100%);
  --cta-hover: linear-gradient(90deg, #e04e0e 0%, #e08820 100%);

  /* Height of the pinned logo strip. The filter bar offsets itself by this
   * so the two stack instead of overlapping. */
  --brandbar-h: 3.1rem;

  /* The marketing site's split: Rubik for headings, Open Sans for text and for
   * the small runs of counts, slugs and labels. */
  --display: "Rubik", "Helvetica Neue", Arial, sans-serif;
  --sans: "Open Sans", "Segoe UI", system-ui, sans-serif;
  --util: "Open Sans", "Segoe UI", system-ui, sans-serif;
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html { scroll-padding-top: calc(var(--brandbar-h) + 7rem); }
body { margin: 0; background: var(--ground); color: var(--ink); font-family: var(--sans); font-size: 16px; line-height: 1.55; }
a { color: var(--navy); text-decoration: none; }
button { font: inherit; color: inherit; }
a:focus-visible, button:focus-visible, input:focus-visible { outline: 2px solid var(--brand-fill); outline-offset: 2px; }
.skip { position: absolute; left: -999px; top: 0; background: var(--navy); color: var(--on-navy); padding: 0.5rem 0.8rem; }
.skip:focus { left: 0.5rem; top: 0.5rem; z-index: 30; }
.wrap { max-width: 1240px; margin: 0 auto; padding: 0 1.5rem; }
.link { background: none; border: 0; padding: 0; color: var(--navy); font-weight: 600; cursor: pointer; }
.link:hover { color: var(--navy-2); }

/* ---- header ---- */
/* Pinned: the lockup stays with you down all 228 cards. Above the filter bar
   in the stacking order, and the filter bar starts below its height. */
.brandbar { position: sticky; top: 0; z-index: 30; background: var(--surface); border-bottom: 1px solid var(--line); }
.brandbar .wrap { display: flex; align-items: center; min-height: var(--brandbar-h); }
.top { padding: 1.4rem 0 1.8rem; border-bottom: 1px solid var(--line); background: var(--surface); }
/* The real lockup replaces the small square mark, and it is aligned on the
 * BASELINE, not the centre. Measured in the artwork: the lockup fills its
 * 70-unit box, but the word "hostbarrel" inside it sits on a baseline 49.8
 * units down, i.e. 0.711 of the height. Centring the box therefore left the
 * word about 1px below the line of type next to it - close enough to look
 * like a mistake rather than a choice.
 *
 * A flex item that is an image has no real baseline, so the browser
 * synthesises one from the bottom of its border box - and ignores margins
 * while doing it. Baseline alignment therefore lands the bottom EDGE of the
 * artwork on the text baseline, leaving the word 0.289 of the height too
 * high. The transform puts that back after layout, so the lockup's own
 * baseline sits on the text's. Derived from --logo-h rather than a magic
 * pixel: it holds at any logo size, at any font size, and if Rubik never
 * loads. (A negative margin does not work here - the synthesised baseline
 * does not see it.) */
.brand { --logo-h: 26px; display: flex; align-items: baseline; gap: 0.6rem; font-family: var(--display); font-weight: 500; font-size: 0.95rem; letter-spacing: 0.01em; }
.brand img { display: block; height: var(--logo-h); width: auto; flex: none; transform: translateY(calc(var(--logo-h) * 0.2886)); }
/* The rule between the lockup and the page name. It cannot be centred on the
 * flex line: that line is sized by the baseline-aligned logo, so its centre
 * sits well above the text. Baseline-aligned instead, then nudged down so it
 * straddles the type - in em, so it tracks the font size. */
.brand .sep { width: 1px; height: 1.2em; background: var(--line); flex: none; align-self: baseline; transform: translateY(0.35em); }
.brand .pg { line-height: 1; color: var(--ink); }
h1 { font-family: var(--display); font-size: clamp(1.6rem, 3.2vw, 2.9rem); line-height: 1.1; font-weight: 700; margin: 0; letter-spacing: -0.01em; text-wrap: balance; max-width: 26ch; }
.intro { margin: 0.8rem 0 0; max-width: 66ch; color: var(--ink-2); font-size: 1.05rem; }
.search { display: flex; align-items: center; gap: 0.6rem; margin: 1.3rem 0 0; max-width: 640px; padding: 0 1rem; height: 3.1rem; background: var(--ground); border: 1.5px solid var(--line); border-radius: 12px; }
.search:focus-within { border-color: var(--brand-fill); background: var(--surface); box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand-fill) 18%, transparent); }
.search svg { width: 20px; height: 20px; flex: none; fill: none; stroke: var(--ink-3); stroke-width: 2; stroke-linecap: round; }
.search input { flex: 1; min-width: 0; height: 100%; border: 0; background: none; outline: none; font: 400 1rem var(--sans); color: var(--ink); }
.search input::placeholder { color: var(--ink-3); }
.how { margin: 0.7rem 0 0; color: var(--ink-3); font-size: 0.88rem; }
/* Header: the pitch keeps its reading measure on the left, and what the offer
   includes takes the space that measure leaves on the right. The two columns are
   sized to bottom out level at 1440: the list at 0.78rem and the h1 clamp up at
   2.9rem put them within 2px of each other. */
.top-grid { display: grid; grid-template-columns: minmax(0, 1fr) 27rem; gap: 1.5rem 2.5rem; align-items: start; }
.top-main { min-width: 0; }
.offer { background: var(--ground); border: 1px solid var(--line); border-radius: 12px; padding: 0.9rem 1.05rem; display: grid; gap: 0.45rem; justify-items: start; }
.offer h2 { font: 700 0.95rem/1.3 var(--display); color: var(--ink); margin: 0; }
.offer ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 0.2rem; font-size: 0.78rem; line-height: 1.38; color: var(--ink-2); }
.offer li { padding-left: 1.1rem; position: relative; }
.offer li::before { content: ""; position: absolute; left: 0; top: 0.52em; width: 0.4rem; height: 0.4rem; border-radius: 50%; background: var(--brand-fill); }
.offer .terms { margin: 0; font-size: 0.76rem; color: var(--ink-3); }
/* Scoped, so the footer button keeps its full size. */
.offer .btn { padding: 0.6rem 1rem; font-size: 0.85rem; }

/* ---- step 1: category tiles ---- */
.browse { padding-top: 1.8rem; }
.browse-head h2, .subs-label { font: 700 1.05rem/1.3 var(--display); margin: 0; letter-spacing: 0.005em; }
.browse-head { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; flex-wrap: wrap; }
.browse-head .link { font-size: 0.9rem; }
/* One line per category: icon, name, count. The examples that used to sit
   under the name are now the tooltip (gallery.js puts them in title), because
   step 1 was costing 628px of scrolling before anyone reached a card. Note a
   native tooltip never appears on a touchscreen - on a phone the examples are
   gone, which is the price of the row. */
.cats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.6rem; margin-top: 0.9rem; }
@media (max-width: 1100px) { .cats { grid-template-columns: repeat(3, 1fr); } }
/* The offer panel drops under the pitch before it can squeeze the measure. */
@media (max-width: 900px) { .top-grid { grid-template-columns: 1fr; } .offer { max-width: 32rem; } }
.cat { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; column-gap: 0.6rem; text-align: left; padding: 0.5rem 0.6rem; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; cursor: pointer; transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease; }
.cat:hover { transform: translateY(-2px); box-shadow: var(--shadow); border-color: hsl(var(--h, 211) 45% 60%); }
.cat-ico { display: grid; place-items: center; width: 34px; height: 34px; border-radius: 9px; background: hsl(var(--h, 211) var(--tint-bg-s) var(--tint-bg-l)); color: hsl(var(--h, 211) 62% var(--tint-l)); }
.cat-ico svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
/* Still used at a larger size in the group headers down the page. */
.cat-ico.sm { width: 38px; height: 38px; border-radius: 10px; flex: none; }
.cat-ico.sm svg { width: 21px; height: 21px; }
.cat-name { font: 700 0.92rem/1.25 var(--display); color: var(--ink); min-width: 0; overflow-wrap: break-word; }
.cat-n { font: 500 0.7rem/1 var(--util); padding: 0.22rem 0.42rem; border-radius: 999px; background: var(--surface-2); color: var(--ink-2); }
.cat-eg { display: none; }
.cat[aria-pressed="true"] { border-color: hsl(var(--h, 211) 55% var(--tint-l)); background: hsl(var(--h, 211) var(--tint-bg-s) var(--tint-bg-l)); box-shadow: 0 0 0 3px hsl(var(--h, 211) 60% 55% / 0.18); }
.cat[aria-pressed="true"] .cat-ico { background: hsl(var(--h, 211) 62% var(--tint-l)); color: var(--surface); }
.cat[aria-pressed="true"] .cat-n { background: var(--surface); color: var(--ink); }

/* ---- sticky bar: where you are + step 2 ---- */
.bar-sentinel { height: 1px; margin-top: 1.6rem; }
.bar { position: sticky; top: var(--brandbar-h); z-index: 20; background: color-mix(in srgb, var(--ground) 92%, transparent); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border-bottom: 1px solid transparent; transition: box-shadow 0.2s ease, border-color 0.2s ease; }
.bar.stuck { border-bottom-color: var(--line); box-shadow: 0 10px 20px -18px rgba(22, 33, 58, 0.5); }
.bar-in { padding-top: 0.7rem; padding-bottom: 0.7rem; display: grid; gap: 0.6rem; }
.bar-row { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; flex-wrap: wrap; }
.crumbs { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.45rem; font-size: 0.92rem; }
.crumbs b { font-family: var(--display); font-weight: 700; color: var(--ink); }
.crumbs .sep { color: var(--ink-3); }
.count { font: 500 0.8rem/1 var(--util); color: var(--ink-3); }
.subs-wrap { display: grid; gap: 0.5rem; }
.subs-label { font-size: 0.9rem; }
/* Kept deliberately small. A category like Photography studio has 18
   specialities, and this bar is sticky: every pixel it spends is a pixel gone
   from the cards for the whole scroll. At the old size those 19 chips ran to
   four rows and held 27% of the window open permanently. */
.subs { display: flex; flex-wrap: wrap; gap: 0.3rem; }
/* No transition on the pressed colours on purpose: the chip must read as
   switched on the same frame as the click. */
.sub { display: inline-flex; align-items: center; gap: 0.35rem; font: 600 0.8rem/1 var(--display); padding: 0.4rem 0.62rem; border: 1px solid var(--line); background: var(--surface); color: var(--ink-2); border-radius: 999px; cursor: pointer; white-space: nowrap; }
.sub:hover { border-color: var(--navy); color: var(--navy); }
.sub .n { font: 600 0.66rem/1 var(--util); padding: 0.1rem 0.28rem; border-radius: 999px; background: var(--surface-2); color: var(--ink-3); }
.sub[aria-pressed="true"] { background: var(--navy); border-color: var(--navy); color: var(--on-navy); }
.sub[aria-pressed="true"] .n { background: color-mix(in srgb, var(--on-navy) 22%, transparent); color: var(--on-navy); }

/* ---- results ---- */
main { outline: none; min-height: 40vh; }
.group { padding: 1.4rem 0 1rem; }
.group + .group { border-top: 1px solid var(--line); }
.group-head { display: flex; align-items: center; gap: 0.8rem; margin-bottom: 1rem; }
.group-txt { flex: 1; min-width: 0; }
.group-head h2 { font: 700 1.25rem/1.2 var(--display); margin: 0; }
.group-head p { margin: 0.1rem 0 0; font-size: 0.88rem; color: var(--ink-3); }
.group-head .link { font-size: 0.85rem; white-space: nowrap; }
.group.solo .group-head { display: none; }
.group.solo { padding-top: 0.6rem; border-top: 0; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 1.3rem; }

.card { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; display: grid; grid-template-rows: auto 1fr; overflow: hidden; transition: transform 0.18s ease, box-shadow 0.18s ease; }
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
/* The box holds its 16:10 shape before the image arrives, so nothing below it
   moves when it does. */
.shot { position: relative; display: block; aspect-ratio: 16 / 10; overflow: hidden; background: var(--surface-2); border-bottom: 1px solid var(--line); }
.shot img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top center; transition: transform 0.35s ease; }
.card:hover .shot img { transform: scale(1.025); }
.shot.no-thumb { display: grid; place-items: center; background: var(--accent, var(--navy)); }
.shot.no-thumb::before { content: attr(data-name); font: 700 1.3rem var(--display); color: #fff; padding: 1rem; text-align: center; }
.look { position: absolute; left: 0.7rem; top: 0.7rem; font: 600 0.68rem/1 var(--display); letter-spacing: 0.05em; text-transform: uppercase; padding: 0.4rem 0.55rem; border-radius: 999px; background: rgba(9, 42, 68, 0.78); color: #fff; backdrop-filter: blur(4px); }
.open { position: absolute; right: 0.7rem; bottom: 0.7rem; display: inline-flex; align-items: center; gap: 0.3rem; font: 700 0.74rem/1 var(--display); letter-spacing: 0.05em; text-transform: uppercase; background: var(--cta); color: #fff; padding: 0.55rem 0.7rem; border-radius: 8px; box-shadow: 0 4px 12px -4px rgba(0, 0, 0, 0.5); opacity: 0; transform: translateY(4px); transition: opacity 0.18s ease, transform 0.18s ease; }
.open svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.card:hover .open, .shot:focus-visible .open { opacity: 1; transform: none; }
@media (hover: none) { .open { opacity: 1; transform: none; } }

.body { padding: 0.95rem 1.1rem 1.1rem; display: grid; gap: 0.4rem; align-content: start; }
.business { display: flex; align-items: center; gap: 0.45rem; margin: 0; font: 600 0.74rem/1.2 var(--display); letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-2); }
.business i { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.name { font: 700 1.2rem/1.2 var(--display); margin: 0; }
.tagline { margin: 0; color: var(--ink-2); font-size: 0.93rem; }
.tags { list-style: none; display: flex; flex-wrap: wrap; gap: 0.3rem; padding: 0; margin: 0.3rem 0 0; }
.tags button { font: 600 0.72rem/1 var(--sans); padding: 0.36rem 0.55rem; border-radius: 999px; border: 1px solid var(--line); background: var(--ground); color: var(--ink-2); cursor: pointer; }
.tags button:hover { border-color: var(--navy); color: var(--navy); }
.tags button.on { background: var(--navy); border-color: var(--navy); color: var(--on-navy); }
.pages { list-style: none; padding: 0; margin: 0.45rem 0 0; display: grid; grid-template-columns: repeat(5, 1fr); gap: 3px; }
.pages li { font-size: 0.66rem; line-height: 1.2; text-align: center; padding: 0.4rem 0.15rem; background: var(--surface-2); border-radius: 4px; color: var(--ink-2); overflow-wrap: anywhere; }
.pages li.own { font-weight: 600; color: var(--ink); }
.slug { margin: 0.3rem 0 0; font: 500 0.7rem/1 var(--util); color: var(--ink-3); }

.empty { text-align: center; padding: 4rem 1rem; }
.empty h2 { font: 700 1.3rem var(--display); margin: 0; }
.empty p { color: var(--ink-2); max-width: 52ch; margin: 0.6rem auto 1.2rem; }
.btn { display: inline-block; font: 700 0.9rem var(--display); padding: 0.7rem 1.1rem; border-radius: 10px; border: 0; background: var(--cta); color: #fff; text-decoration: none; cursor: pointer; }
.btn:hover { background: var(--cta-hover); }

/* ---- footer ---- */
/* Two rows, not a slab. The catalogue used to dead end on the disclaimer, so
   the footer carries one action - the free-website offer these templates are
   - plus the way back to the marketing site and the legal links. */
.foot { background: var(--surface); border-top: 1px solid var(--line); margin-top: 2.4rem; }
.foot-cta { padding-block: 1.3rem; display: flex; flex-wrap: wrap; gap: 1rem 2rem; align-items: center; justify-content: space-between; }
.foot-cta h2 { font: 700 1.12rem/1.25 var(--display); color: var(--ink); margin: 0; letter-spacing: -0.012em; }
.foot-cta p { margin: 0.15rem 0 0; font-size: 0.9rem; color: var(--ink-2); max-width: 56ch; }
.foot-cta .btn { flex: none; }
.foot-base { border-top: 1px solid var(--line); padding-block: 0.85rem 1.5rem; display: flex; flex-wrap: wrap; gap: 0.5rem 1.5rem; justify-content: space-between; align-items: baseline; }
.foot-base p { margin: 0; font-size: 0.8rem; color: var(--ink-3); max-width: 62ch; }
.foot-base nav { display: flex; flex-wrap: wrap; gap: 0.35rem 1rem; font-size: 0.82rem; color: var(--ink-3); }
.foot-base nav a { color: var(--ink-3); }
.foot-base nav a:hover { color: var(--navy); text-decoration: underline; text-underline-offset: 3px; }

/* Phones: two columns of one-line tiles. The speciality chips still swipe. */
@media (max-width: 640px) {
  .wrap { padding: 0 1rem; }
  /* minmax(0,…) so a long category name cannot push the track wider than the
     screen; see the single-column rule below for where two stop fitting. */
  .cats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .subs::-webkit-scrollbar { display: none; }
  .subs { flex-wrap: nowrap; overflow-x: auto; margin-inline: -1rem; padding-inline: 1rem; scrollbar-width: none; }
  .grid { grid-template-columns: 1fr; }
  .group-head .link { display: none; }
  .search input::placeholder { font-size: 0.85rem; }
}
/* Two tiles need about 230px each before "Architecture" and "Photography"
   stop fitting beside an icon and a count. Below that it is one column. */
@media (max-width: 520px) {
  .cats { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  .card:hover, .cat:hover, .card:hover .shot img { transform: none; }
}
