/* ===========================================================================
   Lippukone — header, navigation, buttons
   ===========================================================================

   Sections 4–6 of site.css, split out so the same header can be rendered by
   two documents: Blade on the marketing pages (resources/views/site/partials/
   header.blade.php) and Vue on the buyer app's screens (frontend/apps/buyer/
   src/components/SiteHeader.vue). The two render the same markup with the
   same class names, and this is the one place those names are styled — a rule
   added to one renderer's header without the other is the drift this file
   exists to prevent. Needs tokens.css before it.

   Sections:
     4. Layout primitive (.wrap)
     5. Buttons and controls
     6. Header and navigation
     6b. Account button and menu, "For organizers" group
   =========================================================================== */

/* --- 4. Layout primitive ------------------------------------------------ */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* --- 5. Buttons and controls --------------------------------------------- */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px 20px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font: inherit;
  font-weight: 600;
  font-size: 0.9375rem;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease,
    transform 0.18s ease;
}

.button--lg {
  padding: 14px 26px;
  font-size: 1rem;
}

.button--primary {
  background: var(--accent);
  color: var(--accent-ink);
}

.button--primary:hover {
  transform: translateY(-1px);
  /* Lightening the accent would drift off-brand at every hover; a soft ring
     reads as raised without changing the colour. */
  box-shadow: 0 0 0 4px var(--accent-soft);
}

.button--ghost {
  border-color: var(--line-strong);
  color: var(--ink-strong);
  background: transparent;
}

.button--ghost:hover {
  border-color: var(--accent);
  color: var(--accent-text);
}

.icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--ink-muted);
  cursor: pointer;
  transition: color 0.18s ease, border-color 0.18s ease;
}

.icon-button:hover {
  color: var(--ink-strong);
  border-color: var(--line-strong);
}

.icon-button svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* One button, two glyphs: the moon offers dark, the sun offers light, and
   which one is showing is decided by the theme in force. */
.icon-button__sun {
  display: none;
}

:root[data-theme='dark'] .icon-button__moon {
  display: none;
}

:root[data-theme='dark'] .icon-button__sun {
  display: inline-block;
}

/* --- 6. Header and navigation -------------------------------------------- */

/* The header states its own typography instead of inheriting the page's. On the marketing
   pages it would inherit exactly this from body; in the buyer app the body is Vuetify's, with a
   system font stack and a tighter line-height, and the same header came out in a different
   face. One header, so one rule. */
.site-header,
.site-menu {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: auto;
  letter-spacing: normal;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--line);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: 30px;
  min-height: var(--header-height);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.0625rem;
  letter-spacing: -0.02em;
  color: var(--ink-strong);
  text-decoration: none;
  flex: none;
}

.mark {
  width: 24px;
  height: 24px;
  flex: none;
}

.nav {
  display: none;
  gap: 26px;
  margin-right: auto;
  padding-top: 5px;
}

.nav__link {
  color: var(--ink-muted);
  text-decoration: none;
  font-size: 0.9375rem;
  font-weight: 500;
  transition: color 0.18s ease;
}

.nav__link:hover,
.nav__link[aria-current='page'] {
  color: var(--ink-strong);
}

.site-header__actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

.langs {
  display: none;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
}

.langs__link {
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  text-decoration: none;
}

.langs__link:hover {
  color: var(--ink-strong);
}

.langs__link[aria-current='true'] {
  background: var(--bg-elevated);
  color: var(--ink-strong);
}

.site-header__wallet,
.site-header__cta {
  display: none;
}

.nav-toggle {
  display: inline-flex;
}

/* The theme button follows the language pill: in the header row from 700px, in the menu's
   controls row below it, so a phone's header row is the wordmark, the account and the menu
   button. */
.site-header__theme {
  display: none;
}

@media (min-width: 700px) {
  .langs,
  .site-header__theme {
    display: inline-flex;
  }
}

@media (min-width: 900px) {
  .nav {
    display: flex;
  }

  .site-header__wallet {
    display: inline-flex;
  }

  .nav-toggle {
    display: none;
  }
}

@media (min-width: 1040px) {
  .site-header__cta {
    display: inline-flex;
  }
}

/* The switcher's second home, inside the menu panel. Shown exactly where the header's copy is
   not, so a reader never sees the same three links twice on one screen. Later in the sheet than
   the header rule so the two `display` values resolve in this order. */
.langs--menu {
  display: inline-flex;
}

@media (min-width: 700px) {
  .langs--menu {
    display: none;
  }
}

/*
 * The panel scrolls itself, and it has to: it lives inside .site-header, which is
 * `position: sticky; top: 0`. A sticky box taller than the viewport pins its top at 0 and
 * simply never shows its bottom — the page scrolls underneath it instead, and the language
 * switcher at the panel's end stayed out of reach until the reader had scrolled the whole
 * document to its very last pixel, which is where the sticky containing block finally lets go.
 *
 * Capping the panel at what is left below the header row keeps the sticky box inside the
 * viewport, so the menu is scrolled the way a menu should be. `dvh` after `vh` because a
 * phone's toolbars change the viewport as it scrolls and `vh` is the taller of the two —
 * enough to put the last row back under the address bar. The second declaration is ignored
 * wholesale by a browser that does not know the unit.
 */
.site-menu {
  /* The header row, plus the hairline .site-header draws under the whole thing — both are
     above this panel, and leaving the border out puts the sticky box 1px past the fold. */
  max-height: calc(100vh - var(--header-height) - 1px);
  max-height: calc(100dvh - var(--header-height) - 1px);
  overflow-y: auto;
  /* Reaching the end of the menu must not hand the rest of the gesture to the page behind
     it, which is the same scroll the panel was covering for. */
  overscroll-behavior: contain;
  border-bottom: 1px solid var(--line);
  background: var(--bg-raised);
}




/* --- 6b. Account, login and the organizer group -------------------------- */

/* site.js swaps the guest and signed-in halves of the header by toggling `hidden`, and the
   attribute's own display:none loses to any author `display` — .button is inline-flex, so a
   hidden Login stayed visible beside the account button. Stated once for the whole header. */
.site-header [hidden] {
  display: none !important;
}

/* The one ask the header makes of a guest. Compact on a phone, where it sits
   between the theme button and the menu toggle; a wider pill from 700px. */
.site-header__login {
  padding: 8px 14px;
  font-size: 0.875rem;
}

@media (min-width: 700px) {
  .site-header__login {
    padding: 9px 18px;
    font-size: 0.9375rem;
  }
}

.account {
  position: relative;
}

/* A round button with the person's initials. Sized like .icon-button so the
   row does not change height when Login turns into this. */
.account__button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--accent-text);
  font: inherit;
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}

.account__button:hover,
.account__button[aria-expanded='true'] {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.account__button svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Rendered while the name is still on its way (site.js asks /api/me after
   the page is up): the person icon holds the space, the initials replace it. */
.account__button:not(.account__button--named) .account__initials,
.account__button--named svg {
  display: none;
}

.account__menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 50;
  min-width: 220px;
  padding: 6px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg-raised);
  box-shadow: var(--shadow);
  /*
   * The same lesson the phone panel taught, for the same reason: this hangs off .site-header,
   * which is `position: sticky; top: 0`, so a menu longer than the screen has its bottom
   * pinned out of reach — the page scrolls behind it and sign-out at the end never arrives.
   * Below 900px this menu carries the site's pages and the display controls too, which is
   * exactly when it gets long enough to matter.
   */
  max-height: calc(100vh - var(--header-height) - 16px);
  max-height: calc(100dvh - var(--header-height) - 16px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/*
 * The two blocks this menu carries only while it is the reader's *whole* menu. Each is shown
 * up to the width at which the header row starts offering the same thing itself — the controls
 * to 700px, where the language pill and theme button reappear in the row; the pages to 900px,
 * where the nav row does. Above those widths they would be the same links twice on one screen.
 */
.account__controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 4px 4px 10px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--line);
}

@media (min-width: 700px) {
  .account__controls {
    display: none;
  }
}

.account__pages {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--line);
}

@media (min-width: 900px) {
  .account__pages {
    display: none;
  }
}

.account__who {
  padding: 8px 10px 10px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 6px;
}

.account__name {
  margin: 0;
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--ink-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.account__email {
  margin: 2px 0 0;
  font-size: 0.8125rem;
  color: var(--ink-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.account__link {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 500;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.account__link:hover {
  background: var(--bg-elevated);
  color: var(--ink-strong);
}

.account__link svg {
  width: 18px;
  height: 18px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--ink-muted);
}

.account__link--signout {
  margin-top: 6px;
  border-top: 1px solid var(--line);
  border-radius: 0 0 10px 10px;
  padding-top: 12px;
}

/* The organizer pages under one word in the desktop nav. A native <details>,
   so the group opens without JavaScript; site.js only closes it for an outside
   click and Escape. */
.nav-group {
  position: relative;
}

.nav-group__summary {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  list-style: none;
  cursor: pointer;
}

.nav-group__summary::-webkit-details-marker {
  display: none;
}

.nav-group__summary svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.18s ease;
}

.nav-group[open] .nav-group__summary {
  color: var(--ink-strong);
}

.nav-group[open] .nav-group__summary svg {
  transform: rotate(180deg);
}

.nav-group__panel {
  position: absolute;
  top: calc(100% + 14px);
  left: -10px;
  z-index: 50;
  min-width: 220px;
  padding: 6px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg-raised);
  box-shadow: var(--shadow);
}

.nav-group__link {
  display: block;
  padding: 9px 10px;
  border-radius: 10px;
  color: var(--ink);
  font-size: 0.9375rem;
  font-weight: 500;
  text-decoration: none;
}

.nav-group__link:hover,
.nav-group__link[aria-current='page'] {
  background: var(--bg-elevated);
  color: var(--ink-strong);
}

.nav-group__link--cta {
  margin-top: 6px;
  border-top: 1px solid var(--line);
  border-radius: 0 0 10px 10px;
  padding-top: 12px;
  color: var(--accent-text);
  font-weight: 600;
}

/* --- 6c. The phone menu ---------------------------------------------------- */

/* Opened by the menu button below 900px. Stacked blocks with one gap between them; each block
   is one thing — the account, the site's pages, the display controls — so the eye reads
   groups rather than one long list of rows. */
.site-menu__inner {
  display: flex;
  flex-direction: column;
  /* Named because .site-menu__controls has to cancel exactly one of these gaps, and a second
     literal 20px in this file would be free to drift away from this one. */
  --menu-gap: 20px;
  gap: var(--menu-gap);
  padding-block: 16px 22px;
}

.site-menu__links {
  display: flex;
  flex-direction: column;
}

/* A row per page, a chevron saying it leads somewhere, a hairline between rows and none after
   the last — the group's edge is the gap, not a rule. */
.site-menu__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 0;
  color: var(--ink);
  text-decoration: none;
  font-size: 1.0625rem;
  font-weight: 500;
  border-bottom: 1px solid var(--line);
}

.site-menu__link:last-child {
  border-bottom: 0;
}

.site-menu__link::after {
  content: '';
  width: 7px;
  height: 7px;
  flex: none;
  border-right: 1.5px solid var(--ink-muted);
  border-bottom: 1.5px solid var(--ink-muted);
  transform: rotate(-45deg);
}

.site-menu__link--cta {
  color: var(--accent-text);
  font-weight: 600;
}

.site-menu__link--cta::after {
  border-color: var(--accent-text);
}

.site-menu__heading {
  margin: 0 0 4px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

/*
 * Language and theme side by side, above the pages rather than after them: settings, but the
 * kind a reader reaches for before reading a list rather than after. The hairline is below,
 * which is the side the rest of the panel is on — the same rule under a block that ends the
 * menu and one that opens it are different rules, however identical they look in a diff.
 */
.site-menu__controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--line);
  /*
   * Cancels the panel's gap under this one block. The hairline below the row is the same kind
   * of line as the ones between the page rows under it, and it should sit in the same rhythm:
   * with the gap left in, the first page sat 31px below its line where every other page sits
   * 11px below its own, and the row read as detached from the list it introduces.
   */
  margin-bottom: calc(var(--menu-gap) * -1);
}

.site-menu__theme {
  display: inline-flex;
}

/* From 700px both controls are back in the header row, and this row would repeat them. */
@media (min-width: 700px) {
  .site-menu__controls {
    display: none;
  }
}

/* --- 6d. The sign-out confirmation ----------------------------------------- */

/*
 * A native <dialog>, so the backdrop, the focus trap and Escape are the browser's job. Only
 * the look is ours.
 *
 * `:modal` rather than `[open]`: a <dialog> can also be opened non-modally with show(), and
 * these rules — the centring, the backdrop — only make sense for the modal one. It is opened
 * with showModal() and nothing else, so this is a statement of intent as much as a selector.
 */
.confirm {
  max-width: min(420px, calc(100vw - 32px));
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  color: var(--ink);
  /* The dialog is a top-layer element and inherits from nothing on the page, so the header's
     own typography rules do not reach it. */
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
}

.confirm::backdrop {
  background: rgb(2 6 18 / 62%);
  backdrop-filter: blur(2px);
}

.confirm__box {
  padding: 20px;
}

.confirm__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink-strong);
}

.confirm__message {
  margin: 8px 0 0;
  font-size: 0.9375rem;
  color: var(--ink-muted);
}

/* Wrapping rather than shrinking: these are two sentences-worth of button in three languages,
   and "Kirjaudu ulos" beside "Peruuta" does not fit 420px minus padding on a small phone. */
.confirm__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 20px;
}

.confirm__cancel {
  padding: 9px 18px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  font-size: 0.9375rem;
  cursor: pointer;
}

.confirm__cancel:hover {
  border-color: var(--ink-muted);
  color: var(--ink-strong);
}

/* Not the red of a destructive action: nothing is destroyed by signing out, and a red button
   here would teach the reader to expect worse than what happens. */
.confirm__confirm {
  font-size: 0.9375rem;
}

@media (prefers-reduced-motion: no-preference) {
  .confirm[open] {
    animation: confirm-in 0.16s ease-out;
  }
}

@keyframes confirm-in {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
}
