/* ==========================================================================
   LIGHTSKIES  —  Tebex custom template stylesheet
   Upload this file in the template editor as an Asset named: theme.css
   Loaded by layout.html via /template-assets/theme.css?updated=d7882f56b04f3b496cecf2c2a7069c6c5bc432306d6a6723a9e3e7ffe6dfb867
   --------------------------------------------------------------------------
   Everything you would normally want to tweak lives in the :root block below,
   or in Webstore -> Appearance -> (your template) -> Edit  (see schema.json)
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens
   -------------------------------------------------------------------------- */
:root {
  /* --accent, --cols and --glow are re-declared inline by layout.html so the
     Appearance panel options can override them. These are the fallbacks. */
  --accent: #ff7a18;
  --cols: 3;
  --glow: 55;                      /* 0-100, drives how strong the edge glow is */

  /* Ground is a dark neutral grey, and cards sit a step LIGHTER than it so
     they lift off the page rather than sinking into it. */
  --bg: #101116;
  --bg-card: #1a1c24;
  --bg-card-2: #16181f;
  --bg-raise: #23262f;
  --bg-input: #0c0d12;
  --line: rgba(255, 255, 255, 0.09);
  --line-strong: rgba(255, 255, 255, 0.17);

  --text: #ececf1;
  --text-dim: #9b9ba6;
  --text-faint: #6c6c78;

  /* Accent derivatives. Plain rgba first (older browsers, and it matches the
     default orange), then color-mix so a custom accent colour picked in the
     Appearance panel flows through every glow automatically. */
  --ring: rgba(255, 122, 24, 0.50);
  --ring: color-mix(in srgb, var(--accent) 50%, transparent);
  --glow-strong: rgba(255, 122, 24, 0.40);
  --glow-strong: color-mix(in srgb, var(--accent) 40%, transparent);
  --glow-mid: rgba(255, 122, 24, 0.22);
  --glow-mid: color-mix(in srgb, var(--accent) 22%, transparent);
  --glow-soft: rgba(255, 122, 24, 0.12);
  --glow-soft: color-mix(in srgb, var(--accent) 12%, transparent);
  --glow-faint: rgba(255, 122, 24, 0.06);
  --glow-faint: color-mix(in srgb, var(--accent) 6%, transparent);

  /* Lighter and deeper shades of the accent, used for the gradient on
     category headings. Derived from --accent so a colour picked in the
     Appearance panel carries through. */
  --accent-light: #ffc48f;
  --accent-light: color-mix(in srgb, var(--accent) 45%, #ffffff);
  --accent-deep: #c25305;
  --accent-deep: color-mix(in srgb, var(--accent) 76%, #000000);

  --logo-size: 175px;              /* Appearance panel: Logo size */

  /* Package name colours. The default is overridden by the Appearance panel;
     the three tier colours apply to any package whose name contains Bronze,
     Silver or Gold, so they follow your naming rather than card position. */
  --pkg-name-color: #f5c131;
  --tier-bronze: #cd7f32;
  --tier-silver: #c0c0c0;
  --tier-gold: #ffd700;

  --radius: 14px;
  --radius-sm: 8px;
  --wrap: 1180px;

  /* Fonts. MinecraftLocal / MinecraftTenLocal only exist if you upload font
     assets (see "Use a real Minecraft font" in the README) - otherwise the
     Jersey pixel faces from Google Fonts are used. They were picked over
     other pixel fonts because their capital C stays open: fonts like
     Pixelify Sans and Press Start 2P turn LightCoins into LightOoins and
     Discord into Disoord.

     Both are single-weight, so nothing in the theme asks for bold - a pixel
     font faux-bolded by the browser just smears. Hierarchy comes from size
     and from --font-display being the wider of the two faces. */
  --font-body: 'MinecraftLocal', 'Jersey 15', ui-monospace, 'Courier New', monospace;
  --font-display: 'MinecraftTenLocal', 'MinecraftLocal', 'Jersey 25', 'Jersey 15', ui-monospace, monospace;

  /* Tebex own legal footer (required, cannot be removed) - these official
     variables restyle it so it matches the rest of the store. */
  --tebex-legal-footer-background-color: #101116;
  --tebex-legal-footer-text-color: #8c8c96;
  --tebex-legal-footer-border-color: rgba(255, 255, 255, 0.08);
  --tebex-legal-footer-max-width: 1180px;
  --tebex-legal-footer-logo-color: #8c8c96;
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  /* clip rather than hidden: hidden on html/body turns them into scroll
     containers, which breaks the sticky top bar in some browsers */
  overflow-x: clip;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 17.5px;
  line-height: 1.65;
  letter-spacing: 0.01em;
}

img, svg { max-width: 100%; }
a { color: var(--accent); text-decoration: none; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.35;
  margin: 0;
  letter-spacing: 0.02em;
}

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

::selection { background: var(--ring); color: #fff; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 20px;
  position: relative;
  z-index: 1;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--accent);
  color: #000;
  padding: 10px 16px;
  z-index: 99;
}
.skip:focus { left: 8px; top: 8px; }

/* --------------------------------------------------------------------------
   3. Background glows  (faint orange from the top + all four edges)
   -------------------------------------------------------------------------- */
.glow-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: calc(var(--glow) / 100);
  background:
    /* top - the brightest one */
    radial-gradient(1250px 540px at 50% -170px, var(--glow-strong), transparent 72%),
    /* left edge */
    radial-gradient(520px 900px at -12% 38%, var(--glow-soft), transparent 70%),
    /* right edge */
    radial-gradient(520px 900px at 112% 38%, var(--glow-soft), transparent 70%),
    /* bottom edge */
    radial-gradient(1100px 320px at 50% 116%, var(--glow-soft), transparent 74%);
}

/* A second glow that scrolls away with the page, so the header area feels lit
   rather than the whole viewport being permanently washed. */
.glow-top {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: min(1100px, 100%);
  height: 520px;
  pointer-events: none;
  z-index: 0;
  background: radial-gradient(60% 60% at 50% 0%, var(--glow-mid), transparent 70%);
}

/* --------------------------------------------------------------------------
   4. Top bar
   -------------------------------------------------------------------------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(16, 17, 22, 0.82);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 1px 0 0 var(--glow-faint), 0 8px 30px -22px var(--glow-mid);
}

.topbar-inner {
  display: flex;
  align-items: center;
  /* Only the account / basket / Discord buttons live up here, so they sit on
     the right. The .brand and .topnav rules below are kept in case you want to
     put a logo or category links back in layout.html. */
  justify-content: flex-end;
  gap: 18px;
  min-height: 62px;
  padding: 8px 20px;
  max-width: var(--wrap);
  margin: 0 auto;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
  color: var(--text);
  font-family: var(--font-display);
  font-size: 15.2px;
  letter-spacing: 0.04em;
}
.brand img { max-height: 30px; width: auto; display: block; }
.brand:hover { color: var(--accent); }

.topnav {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.topnav::-webkit-scrollbar { display: none; }

.topnav a {
  flex: 0 0 auto;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  /* Left in the category's own capitalisation - pixel fonts get hard to read
     when they are forced to uppercase at small sizes. */
  font-size: 15.2px;
  letter-spacing: 0.04em;
  white-space: nowrap;
  transition: color 0.16s ease, background 0.16s ease;
}
.topnav a:hover,
.topnav a[aria-current="page"] { color: var(--text); background: rgba(255, 255, 255, 0.05); }
.topnav a[aria-current="page"] { box-shadow: inset 0 -2px 0 0 var(--accent); }

.topbar-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}


.user-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  color: var(--text-dim);
  letter-spacing: 0.05em;
  padding: 0 4px;
}
.user-chip strong { color: var(--text); font-weight: 400; }

/* --------------------------------------------------------------------------
   5. Buttons
   -------------------------------------------------------------------------- */
.btn {
  --btn-bg: var(--bg-raise);
  --btn-fg: var(--text);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px 18px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font: inherit;
  font-family: var(--font-display);
  font-size: 13.5px;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: transform 0.14s ease, box-shadow 0.22s ease,
              border-color 0.18s ease, background 0.18s ease, color 0.18s ease;
  -webkit-appearance: none;
  appearance: none;
}
.btn:hover {
  border-color: var(--ring);
  box-shadow: 0 0 0 1px var(--glow-soft), 0 0 26px -6px var(--glow-mid);
  color: #fff;
}
.btn:active { transform: translateY(1px); }
.btn[disabled], .btn.is-disabled {
  opacity: 0.4;
  cursor: not-allowed;
  box-shadow: none;
  border-color: var(--line);
}

.btn-primary {
  --btn-bg: var(--accent);
  --btn-fg: #0a0500;
  border-color: transparent;
  box-shadow: 0 0 22px -8px var(--glow-strong);
}
.btn-primary:hover {
  color: #0a0500;
  box-shadow: 0 0 0 1px var(--ring), 0 0 34px -6px var(--glow-strong);
  filter: brightness(1.08);
}

.btn-ghost { --btn-bg: transparent; }

/* Discord blurple, kept as its own colour rather than the accent so it reads
   as "that's the Discord button" at a glance. */
.btn-discord {
  --btn-bg: #5865f2;
  --btn-fg: #ffffff;
  border-color: transparent;
  box-shadow: 0 0 20px -8px rgba(88, 101, 242, 0.75);
}
.btn-discord:hover {
  color: #ffffff;
  border-color: rgba(120, 132, 255, 0.6);
  box-shadow: 0 0 0 1px rgba(120, 132, 255, 0.5), 0 0 30px -6px rgba(88, 101, 242, 0.8);
  filter: brightness(1.08);
}

.btn-sm { padding: 8px 12px; font-size: 12px; }
.btn-block { width: 100%; }
.btn-lg { padding: 14px 24px; font-size: 15.2px; }

.basket-btn { gap: 10px; }
.basket-btn .count {
  display: inline-grid;
  place-items: center;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border-radius: 6px;
  background: var(--accent);
  color: #0a0500;
  font-size: 12px;
}

/* --------------------------------------------------------------------------
   6. Hero  (logo / subtext / server IP)
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  text-align: center;
  padding: clamp(46px, 9vw, 86px) 0 clamp(30px, 5vw, 50px);
}

.hero-logo {
  max-height: var(--logo-size, 175px);
  width: auto;
  filter: drop-shadow(0 0 34px var(--glow-mid));
}

.hero-title {
  font-family: var(--font-display);
  font-size: clamp(30.4px, 5.4vw, 56.2px);
  letter-spacing: 0.04em;
  text-shadow: 0 0 34px var(--glow-mid);
}

.hero-sub {
  margin: 18px auto 0;
  max-width: 620px;
  color: var(--text-dim);
  font-size: clamp(16px, 1.8vw, 19px);
  letter-spacing: 0.02em;
}

.ip-box {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 26px;
  padding: 11px 20px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(0, 0, 0, 0.3));
  color: var(--text);
  font-family: var(--font-display);
  font-size: clamp(14px, 1.8vw, 17.5px);
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: border-color 0.18s ease, box-shadow 0.25s ease, transform 0.14s ease;
}
.ip-box:hover {
  transform: translateY(-2px);
  border-color: var(--ring);
  box-shadow: 0 0 0 1px var(--glow-soft), 0 10px 30px -14px var(--glow-mid), 0 0 40px -8px var(--glow-soft);
}
.ip-box { position: relative; }
.ip-box .ip-value { color: var(--text); }
.ip-box:hover .ip-value { color: var(--accent); }

/* The hint sits under the pill so revealing it never resizes the pill */
.ip-box .ip-hint {
  position: absolute;
  top: calc(100% + 9px);
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-body);
  font-size: 12px;
  letter-spacing: 0.12em;
  white-space: nowrap;
  color: var(--text-faint);
  opacity: 0;
  transition: opacity 0.18s ease;
}
.ip-box:hover .ip-hint,
.ip-box:focus-visible .ip-hint,
.ip-box.copied .ip-hint { opacity: 1; }

.ip-box.copied { border-color: var(--ring); }
.ip-box.copied .ip-hint { color: var(--accent); }

.store-copy {
  max-width: 760px;
  margin: 0 auto 40px;
  color: var(--text-dim);
  text-align: center;
  font-size: 17px;
}
.store-copy h1, .store-copy h2, .store-copy h3 { color: var(--text); margin-bottom: 0.4em; }

/* --------------------------------------------------------------------------
   7. Sections + category headings (incl. animated rainbow)
   -------------------------------------------------------------------------- */
.section { padding: clamp(26px, 4vw, 44px) 0; }

.section-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin-bottom: clamp(20px, 3vw, 30px);
  text-align: center;
}

.section-head-row {
  display: flex;
  align-items: baseline;
  justify-content: center;
  flex-wrap: wrap;
  gap: 12px;
}

/* Category headings: a static top-to-bottom accent gradient. drop-shadow is
   used rather than text-shadow because the glyphs are filled by the gradient
   and a text-shadow would show through the transparent fill as a blur. */
.section-title {
  font-family: var(--font-display);
  font-size: clamp(26px, 4.2vw, 44px);
  letter-spacing: 0.04em;
  background-image: linear-gradient(180deg, var(--accent-light) 0%, var(--accent) 56%, var(--accent-deep) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 0 20px var(--glow-mid));
}

.section-desc {
  color: var(--text-dim);
  font-size: 17px;
  max-width: 680px;
}

.section-link {
  font-family: var(--font-body);
  font-size: 13.5px;
  letter-spacing: 0.1em;
  color: var(--text-faint);
}
.section-link:hover { color: var(--accent); }

/* Animated rainbow text - used for whichever category you name in the
   "Featured category" option in the Appearance panel. Works on any element.

   The gradient tile is a fixed 420px wide and starts and ends on the same red,
   so it tiles seamlessly, and the animation slides it by exactly one tile
   width. Keeping both in pixels (rather than percentages, which resolve
   against the element's own width) is what makes the movement continuous and
   the loop invisible at any text length. */
.rainbow {
  background-image: linear-gradient(
    90deg,
    #ff4d4d 0%, #ff9f1a 14.28%, #ffe83d 28.57%, #4dff88 42.85%,
    #3ddbff 57.14%, #8a6bff 71.42%, #ff5cd2 85.71%, #ff4d4d 100%
  );
  background-size: 420px 100%;
  background-repeat: repeat;
  background-position: 0 0;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  animation: rainbow-slide 4s linear infinite;
  filter: drop-shadow(0 0 16px rgba(255, 255, 255, 0.16));
  text-shadow: none;
}
@keyframes rainbow-slide {
  from { background-position: 0 0; }
  to { background-position: 420px 0; }
}

/* .section.is-featured is on the featured category's section if you want to
   style it differently. Its cards deliberately hover the same orange as the
   rest of the store - the animated heading is what marks it out. */

/* --------------------------------------------------------------------------
   8. Package grid + cards
   -------------------------------------------------------------------------- */
.grid {
  display: grid;
  gap: 18px;
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 620px) {
  .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1000px) {
  /* --cols comes from the "Packages per row" option (default 3, so a
     6-package category lands as a tidy 3 x 2 block) */
  .grid { grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr)); gap: 22px; }
}

.pkg {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 24px 18px 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: linear-gradient(180deg, var(--bg-card) 0%, var(--bg-card-2) 100%);
  text-align: center;
  overflow: hidden;
  transition: transform 0.18s ease, border-color 0.2s ease,
              box-shadow 0.28s ease, background 0.28s ease;
}

/* The outer aura + highlight on hover.
   z-index matters: grid items paint in document order, so without it a card's
   glow gets covered by the background of the cards after it and only shows on
   the outer edges of the row. The first shadow has no offset so the halo is
   even on all four sides, top included. */
.pkg:hover {
  z-index: 2;
  transform: translateY(-4px);
  border-color: var(--ring);
  background: linear-gradient(180deg, var(--glow-soft) 0%, var(--bg-card-2) 64%);
  box-shadow:
    0 0 0 1px var(--ring),
    0 0 26px -4px var(--glow-mid),
    0 12px 36px -12px var(--glow-mid),
    0 0 74px -14px var(--glow-soft);
}
.pkg:focus-within {
  border-color: var(--ring);
  box-shadow: 0 0 0 1px var(--glow-soft), 0 0 40px -12px var(--glow-mid);
}

/* lit line across the top edge of a hovered card */
.pkg::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  box-shadow: 0 0 12px var(--glow-strong);
  opacity: 0;
  transition: opacity 0.25s ease;
}
.pkg:hover::before { opacity: 1; }

/* Corner badge: bonus text from the package name, or a discount percentage.
   Green so it reads as "extra" against the orange the rest of the store uses. */
.pkg-badge {
  position: absolute;
  top: 11px;
  right: 11px;
  z-index: 1;
  max-width: calc(100% - 22px);
  padding: 5px 11px;
  border: 1px solid rgba(72, 214, 128, 0.45);
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(72, 214, 128, 0.22), rgba(72, 214, 128, 0.1));
  color: #9cf0bd;
  font-family: var(--font-display);
  font-size: 13px;
  letter-spacing: 0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  box-shadow: 0 0 18px -6px rgba(72, 214, 128, 0.55);
  transition: color 0.18s ease, border-color 0.18s ease, box-shadow 0.22s ease;
}
/* Same badge, in the flow rather than pinned to a corner (package page) */
.badge-inline {
  position: static;
  display: inline-block;
  max-width: 100%;
  margin: 0 0 18px;
}

.pkg:hover .pkg-badge {
  color: #c4f9db;
  border-color: rgba(72, 214, 128, 0.7);
  box-shadow: 0 0 22px -5px rgba(72, 214, 128, 0.7);
}

.pkg-media {
  display: grid;
  place-items: center;
  width: 100%;
  height: 132px;
  margin-top: 14px;
}
.pkg-img {
  max-height: 132px;
  width: auto;
  transition: transform 0.2s ease, filter 0.25s ease;
  /* Uncomment for crisp pixel-art package images:
  image-rendering: pixelated; */
}
.pkg:hover .pkg-img {
  transform: translateY(-2px) scale(1.03);
  filter: drop-shadow(0 8px 18px var(--glow-mid));
}
.pkg-name {
  font-family: var(--font-display);
  font-size: clamp(17px, 1.7vw, 22px);
  letter-spacing: 0.03em;
  color: var(--pkg-name-color);
  overflow-wrap: anywhere;
  transition: color 0.18s ease, text-shadow 0.25s ease;
}

/* Tier colours, keyed off the package name */
.pkg--bronze .pkg-name { color: var(--tier-bronze); }
.pkg--silver .pkg-name { color: var(--tier-silver); }
.pkg--gold   .pkg-name { color: var(--tier-gold); }

/* Hover brightens the name rather than recolouring it, so bronze/silver/gold
   and the default gold survive the hover state. */
.pkg:hover .pkg-name {
  text-shadow: 0 0 24px currentColor;
  filter: brightness(1.12);
}
a.pkg-name-link { color: inherit; display: block; }

.pkg-price {
  font-family: var(--font-display);
  font-size: clamp(15.2px, 1.4vw, 18.7px);
  color: var(--text);
  letter-spacing: 0.03em;
}
.pkg-price del { color: var(--text-faint); font-size: 0.78em; margin-right: 6px; }
.pkg-price .cur { color: var(--text-faint); font-size: 0.7em; }
.pkg-free { color: #7ee2a8; }

/* Price button. The card's call to action is the price itself, the way most
   Minecraft stores do it. To label it "Add to basket" instead, change the
   button text in package-card.twig. */
.pkg-foot {
  margin-top: auto;
  width: 100%;
  padding-top: 10px;
  display: flex;
  justify-content: center;
}
.pkg-foot .btn { flex: 0 1 auto; min-width: 145px; max-width: 100%; }
.pkg-foot .btn del { opacity: 0.55; font-size: 0.8em; margin-right: 7px; font-weight: inherit; }
.pkg-foot .btn .cur { font-size: 0.72em; opacity: 0.75; }
/* The price inside a button is one flex item so the parts do not get pushed
   apart by the button's gap, and "/mo" reads as part of the price itself. */
.btn .amount { white-space: nowrap; }
.btn .per, .pkg-price .per { font-size: 0.75em; opacity: 0.9; }

.pkg-note { color: var(--text-faint); font-size: 13.5px; letter-spacing: 0.04em; }

.pkg-desc {
  color: var(--text-dim);
  font-size: 16px;
  line-height: 1.65;
}
.pkg-desc ul, .pkg-desc ol { text-align: left; padding-left: 18px; margin: 0; }

/* Package descriptions inside a card. Kept left-aligned like the rest of the
   card copy, and capped so one very long description cannot stretch a whole
   row of cards - the full text is always on the package's own page. */
.pkg .pkg-desc {
  width: 100%;
  text-align: left;
  max-height: 15em;
  overflow: hidden;
}
.pkg .pkg-desc p { margin: 0 0 0.7em; }
.pkg .pkg-desc p:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   9. Category tiles  (used when "Homepage layout" = Category tiles)
   -------------------------------------------------------------------------- */
.tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 190px;
  padding: 26px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: linear-gradient(180deg, var(--bg-card) 0%, var(--bg-card-2) 100%);
  color: var(--text);
  text-align: center;
  transition: transform 0.18s ease, border-color 0.2s ease, box-shadow 0.28s ease, background 0.28s ease;
}
.tile:hover {
  transform: translateY(-4px);
  border-color: var(--ring);
  background: linear-gradient(180deg, var(--glow-faint) 0%, var(--bg-card-2) 62%);
  box-shadow: 0 0 0 1px var(--glow-soft), 0 14px 34px -18px var(--glow-mid), 0 0 54px -10px var(--glow-soft);
}
/* A lone card or tile centres itself rather than sitting in the first column
   of an otherwise empty row — a category with one package, or the
   "Browse <category>" fallback. Partly-filled last rows are left alone;
   that is normal grid behaviour. */
/* A placeholder or empty state inside a grid spans the whole row */
.grid > .empty { grid-column: 1 / -1; }

.grid > .tile:only-child,
.grid > .pkg:only-child {
  grid-column: 1 / -1;
  justify-self: center;
  width: min(420px, 100%);
}

.tile img { max-height: 84px; width: auto; }
.tile-name {
  font-family: var(--font-display);
  font-size: clamp(16px, 1.7vw, 21px);
  letter-spacing: 0.04em;
}
.tile:hover .tile-name { color: var(--accent); }
.tile-count { font-size: 13.5px; color: var(--text-faint); letter-spacing: 0.08em; }

/* --------------------------------------------------------------------------
   10. Panels, tables, forms  (package page, basket, login, options)
   -------------------------------------------------------------------------- */
.panel {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: linear-gradient(180deg, var(--bg-card) 0%, var(--bg-card-2) 100%);
  padding: clamp(18px, 3vw, 28px);
}
.panel + .panel { margin-top: 18px; }
.panel-title {
  font-family: var(--font-display);
  font-size: 17px;
  letter-spacing: 0.05em;
  margin-bottom: 16px;
}

.split {
  display: grid;
  gap: 24px;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}
@media (min-width: 900px) {
  .split { grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr); }
  .split-sticky { position: sticky; top: 88px; }
}

.crumbs {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  padding: 22px 0 0;
  font-size: 13.5px;
  letter-spacing: 0.08em;
  color: var(--text-faint);
}
.crumbs a { color: var(--text-dim); }
.crumbs a:hover { color: var(--accent); }

.rows { width: 100%; border-collapse: collapse; }
.rows th, .rows td {
  padding: 14px 10px;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: middle;
}
.rows th {
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.1em;
  color: var(--text-faint);
  font-weight: 400;
}
.rows tr:last-child td { border-bottom: 0; }
.rows .num { text-align: right; white-space: nowrap; font-family: var(--font-display); font-size: 14px; }

.total-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding-top: 16px;
  margin-top: 4px;
  border-top: 1px solid var(--line-strong);
  font-family: var(--font-display);
}
.total-row .total-value { font-size: clamp(18.7px, 2.4vw, 25.7px); color: var(--accent); }

.field { display: block; margin-bottom: 16px; text-align: left; }
.field > span {
  display: block;
  margin-bottom: 7px;
  font-size: 13.5px;
  letter-spacing: 0.1em;
  color: var(--text-faint);
}
.field small { display: block; margin-top: 6px; color: var(--text-faint); font-size: 13.5px; }

input[type="text"], input[type="number"], input[type="email"],
input[type="search"], select, textarea {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
  color: var(--text);
  font: inherit;
  font-size: 17px;
  transition: border-color 0.18s ease, box-shadow 0.22s ease;
  -webkit-appearance: none;
  appearance: none;
}
select {
  background-image: linear-gradient(45deg, transparent 50%, var(--text-dim) 50%),
                    linear-gradient(135deg, var(--text-dim) 50%, transparent 50%);
  background-position: calc(100% - 20px) center, calc(100% - 14px) center;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 38px;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--ring);
  box-shadow: 0 0 0 1px var(--glow-soft), 0 0 24px -10px var(--glow-mid);
}
input::placeholder, textarea::placeholder { color: var(--text-faint); }

.actions { display: flex; flex-wrap: wrap; gap: 10px; }
.actions .btn { flex: 1 1 auto; }

.empty {
  padding: clamp(30px, 6vw, 60px) 20px;
  text-align: center;
  color: var(--text-dim);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
}
.empty h2 { margin-bottom: 10px; font-size: 18.7px; }

.media-strip { display: grid; gap: 12px; }
.media-strip img, .media-strip iframe {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: #000;
}
.media-strip iframe { aspect-ratio: 16 / 9; height: auto; }

/* --------------------------------------------------------------------------
   11. Footer + legal links
   -------------------------------------------------------------------------- */
.site-footer {
  position: relative;
  z-index: 1;
  margin-top: clamp(40px, 7vw, 80px);
  padding: 30px 0 26px;
  border-top: 1px solid var(--line);
  background: linear-gradient(180deg, transparent, var(--glow-faint));
}

.footer-inner {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  text-align: center;
}

.legal-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px 4px;
}

/* "not tiny but smaller" - 13px against the 15px body */
.legal-link {
  padding: 7px 12px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text-dim);
  font: inherit;
  font-size: 15.2px;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: color 0.16s ease, border-color 0.18s ease, box-shadow 0.22s ease;
}
.legal-link:hover {
  color: var(--accent);
  border-color: var(--ring);
  box-shadow: 0 0 22px -10px var(--glow-mid);
}

.footer-meta { color: var(--text-faint); font-size: 14px; letter-spacing: 0.04em; }
.footer-meta a { color: var(--text-dim); }
.footer-meta a:hover { color: var(--accent); }

/* --------------------------------------------------------------------------
   11b. Basket panel

   Tebex has no basket page - Exo opens a panel, which is why /checkout 404s.
   This one is rendered server-side from the `basket` object and just slid in
   and out, so it needs no routes at all.
   -------------------------------------------------------------------------- */
.basket-scrim {
  position: fixed;
  inset: 0;
  z-index: 60;
  border: 0;
  padding: 0;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  cursor: pointer;
  animation: basket-fade 0.2s ease-out;
}
@keyframes basket-fade { from { opacity: 0; } to { opacity: 1; } }

.basket-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 61;
  width: min(430px, 100%);
  display: flex;
  flex-direction: column;
  border-left: 1px solid var(--line-strong);
  background: var(--bg-card);
  box-shadow: -30px 0 70px -30px #000, 0 0 60px -20px var(--glow-mid);
  animation: basket-in 0.22s ease-out;
}
@keyframes basket-in { from { transform: translateX(100%); } to { transform: none; } }

.basket-panel[hidden], .basket-scrim[hidden] { display: none !important; }

.basket-head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px;
  border-bottom: 1px solid var(--line);
}
.basket-head h2 {
  flex: 1 1 auto;
  font-size: 19px;
  letter-spacing: 0.04em;
}

.basket-body { padding: 18px; overflow-y: auto; flex: 1 1 auto; }
.basket-foot { padding: 18px; border-top: 1px solid var(--line); }

.basket-row {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 13px 0;
  border-bottom: 1px solid var(--line);
}
.basket-row:last-child { border-bottom: 0; }
.basket-row .name { flex: 1 1 auto; font-size: 15.5px; overflow-wrap: anywhere; }
.basket-row .qty { color: var(--text-faint); font-size: 13.5px; white-space: nowrap; }
.basket-row .price {
  font-family: var(--font-display);
  font-size: 15px;
  white-space: nowrap;
}
.basket-row .drop {
  flex: 0 0 auto;
  border: 0;
  background: none;
  color: var(--text-faint);
  font: inherit;
  font-size: 13.5px;
  cursor: pointer;
  padding: 0 2px;
}
.basket-row .drop:hover { color: var(--accent); }

/* --------------------------------------------------------------------------
   12. Modal (legal documents)
   -------------------------------------------------------------------------- */
.modal {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: center;
  padding: 18px;
}
.modal[hidden] { display: none !important; }

.modal-backdrop {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  border: 0;
  padding: 0;
  cursor: pointer;
}

.modal-card {
  position: relative;
  width: min(760px, 100%);
  max-height: min(80vh, 760px);
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg-card);
  box-shadow: 0 0 0 1px var(--glow-soft), 0 40px 90px -40px #000,
              0 0 70px -20px var(--glow-mid);
  animation: modal-in 0.18s ease-out;
}
@keyframes modal-in {
  from { opacity: 0; transform: translateY(8px) scale(0.99); }
  to { opacity: 1; transform: none; }
}

.modal-head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 18px 14px;
  border-bottom: 1px solid var(--line);
}
.modal-head h3 {
  flex: 1 1 auto;
  font-size: 17px;
  letter-spacing: 0.05em;
  overflow-wrap: anywhere;
}
.modal-x {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text-dim);
  font-family: var(--font-body);
  font-size: 18.7px;
  line-height: 1;
  cursor: pointer;
}
.modal-x:hover { color: var(--accent); border-color: var(--ring); }

.modal-body {
  padding: 18px;
  overflow-y: auto;
  color: var(--text-dim);
  font-size: 15.8px;
  line-height: 1.75;
}
.modal-body h1, .modal-body h2, .modal-body h3, .modal-body h4 {
  color: var(--text);
  font-size: 15.2px;
  letter-spacing: 0.04em;
  margin: 1.4em 0 0.5em;
}
.modal-body > :first-child { margin-top: 0; }
.modal-body ul, .modal-body ol { padding-left: 20px; }
.modal-body li { margin-bottom: 0.35em; }
.modal-body a { color: var(--accent); text-decoration: underline; }
.modal-body hr { border: 0; border-top: 1px solid var(--line); margin: 1.4em 0; }

.modal-loading { color: var(--text-faint); font-size: 14px; letter-spacing: 0.08em; }

/* --------------------------------------------------------------------------
   13. Toast / store message
   -------------------------------------------------------------------------- */
.toast {
  position: fixed;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%);
  z-index: 70;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: min(520px, calc(100vw - 32px));
  padding: 13px 16px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  color: var(--text);
  font-size: 15.2px;
  box-shadow: 0 20px 50px -24px #000, 0 0 40px -16px var(--glow-mid);
}
.toast.is-error { border-color: rgba(255, 86, 86, 0.5); }
.toast.is-success { border-color: rgba(96, 220, 140, 0.45); }
.toast button {
  border: 0;
  background: none;
  color: var(--text-faint);
  font: inherit;
  cursor: pointer;
  padding: 0 2px;
}
.toast button:hover { color: var(--accent); }

.notice {
  margin: 18px 0 0;
  padding: 13px 16px;
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.02);
  color: var(--text-dim);
  font-size: 15.2px;
}

/* --------------------------------------------------------------------------
   14. Small screens
   -------------------------------------------------------------------------- */
@media (max-width: 760px) {
  /* Two rows: brand + actions on top, scrolling category nav underneath */
  .topbar-inner { flex-wrap: wrap; gap: 8px 12px; padding: 10px 14px; }
  .brand { font-size: 13.5px; }
  .brand img { max-height: 24px; }
  .topbar-actions { margin-left: auto; }
  .topnav { order: 3; flex: 1 0 100%; }

  .ip-box { gap: 8px; padding: 10px 12px; max-width: 100%; }
  .ip-box .ip-value { overflow-wrap: anywhere; }
  .ip-box .ip-hint { display: none; }

  .pkg-media, .pkg-img { height: 110px; max-height: 110px; }
  .crumbs { padding-top: 16px; }
}

@media (max-width: 480px) {
  .hide-sm { display: none; }
}

/* --------------------------------------------------------------------------
   15. Accessibility / motion
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  /* The rainbow heading is a colour shift rather than motion across the
     screen, and it is the one animation on the store that is meant to be
     noticed, so it keeps running here - just at half speed. Everything else
     (card lifts, hover transitions) is still switched off above. */
  .rainbow {
    animation-duration: 8s !important;
    animation-iteration-count: infinite !important;
  }
  .pkg:hover, .tile:hover, .ip-box:hover { transform: none; }
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
