/* App chrome — 232px sidebar + 56px topbar (design-system.md · ADR-0021)
 *
 * Responsive contract:
 *   ≥1024  fixed sidebar
 *   ≤1023  one compact topbar + drawer
 *   ≤859   denser page padding (DS: 16px under 860px)
 *   ≤640   phone / 375px signing surface
 * Safe-area insets for notched devices (viewport-fit=cover).
 *
 * Navigation is multipage (MPA): each menu item is a full document load.
 * Cross-document View Transitions keep chrome continuous where the browser
 * supports them — not a soft-router, progressive enhancement only.
 */

/* Same-origin multipage navigations may cross-fade (Chrome/Edge; ignored elsewhere). */
@view-transition {
  navigation: auto;
}

.g-app {
  display: flex;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--carta);
  /* Notch / home indicator */
  padding-left: env(safe-area-inset-left, 0);
  padding-right: env(safe-area-inset-right, 0);
}

/* —— Sidebar —— */
.g-sidebar {
  width: var(--w-sidebar);
  flex-shrink: 0;
  background: var(--fondo-app);
  border-right: 1px solid var(--bordo);
  display: flex;
  flex-direction: column;
  padding: var(--s4) 0 var(--s3);
  padding-top: max(var(--s4), env(safe-area-inset-top, 0px));
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  overflow-y: auto;
  overflow-x: hidden;
  z-index: 20;
}

.g-sidebar__brand {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: 0 var(--s4) var(--s4);
  border-bottom: 1px solid var(--bordo);
  margin-bottom: var(--s3);
  min-height: calc(var(--h-topbar) - var(--s4));
  text-decoration: none;
  color: inherit;
}

.g-sidebar__brand:focus-visible {
  outline: 2px solid var(--arancio);
  outline-offset: -2px;
}

.g-sidebar__brand img {
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  display: block;
}

.g-sidebar__name {
  font-weight: 700;
  letter-spacing: 0.06em;
  font-size: var(--fs-15);
  color: var(--ink);
  line-height: 1;
}

@media (hover: hover) {
  .g-sidebar__brand:hover .g-sidebar__name {
    color: var(--verde);
  }
}

.g-sidebar__nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 0 var(--s2);
  flex: 1;
}

/* A group title names the links below it and is not one of them: quieter than the links,
   separated from the group above, no pointer. The links carry the ink. */
.g-sidebar__kicker {
  margin: var(--s4) 0 var(--s1);
  padding: var(--s3) var(--s3) 0;
  border-top: 1px solid var(--bordo);
  font-family: var(--mono);
  font-size: var(--fs-10);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
  cursor: default;
  user-select: none;
}

.g-sidebar__kicker:first-child {
  margin-top: var(--s1);
  padding-top: 0;
  border-top: 0;
}

.g-sidebar__label-short {
  display: none;
}

.g-sidebar__nav-end {
  display: none;
}

.g-sidebar__nav a {
  display: flex;
  align-items: center;
  min-height: var(--touch-min);
  padding: 0.5rem var(--s3);
  border-radius: var(--r-control);
  color: var(--ink);
  text-decoration: none;
  font-size: var(--fs-15);
  font-weight: 500;
  line-height: 1.3;
  border: 1px solid transparent;
}

@media (hover: hover) {
  .g-sidebar__nav a:hover {
    background: var(--foglio);
    color: var(--ink);
  }
}

.g-sidebar__nav a:focus-visible {
  outline: 2px solid var(--arancio);
  outline-offset: 1px;
}

.g-sidebar__nav a[aria-current="page"] {
  background: var(--foglio);
  color: var(--verde);
  font-weight: 700;
  border-color: var(--bordo);
}

.g-sidebar__foot {
  padding: var(--s3) var(--s4) 0;
  padding-bottom: env(safe-area-inset-bottom, 0);
  border-top: 1px solid var(--bordo);
  margin-top: var(--s3);
  font-size: var(--fs-12);
  line-height: 1.4;
  color: var(--ink-muted);
}

.g-sidebar__foot p {
  margin: 0;
}

.g-sidebar__foot p + p {
  margin-top: var(--s1);
}

/* The varco: no product chrome before identity. An empty 232px sidebar
   next to a blank column was the “white page + empty menu”. */
body:not([data-session="authed"]) .g-app {
  display: block;
}

body[data-session="pending"] #panel-login,
body[data-session="authed"] #panel-login {
  display: none;
}

/* —— Main column —— */
.g-column {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: var(--carta);
}

.g-topbar {
  height: var(--h-topbar);
  min-height: var(--h-topbar);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: nowrap;
  gap: var(--s3);
  padding: 0 var(--pad-page-x);
  padding-top: env(safe-area-inset-top, 0);
  background: var(--chrome);
  color: #f3f5f0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.2);
  z-index: 15;
}

.g-topbar__screen {
  /* Nav already marks the place (aria-current). Repeating the label here
     made menu and title read as the same word three times. */
  display: none;
}

.g-topbar__brand {
  display: none;
}

.g-topbar__user {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: nowrap;
  gap: var(--s3);
  margin-left: auto;
  min-width: 0;
  font-size: var(--fs-13);
}

.g-topbar__who {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  min-width: 0;
}

.g-topbar__name {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 12rem;
}

.g-topbar__org {
  color: rgba(243, 245, 240, 0.82);
  white-space: nowrap;
}

.g-topbar__org::before {
  content: "·";
  margin-right: 0.4em;
  opacity: 0.75;
}

.g-topbar__roles {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: var(--s1);
  flex-shrink: 0;
}

.g-theme {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  color: #f3f5f0;
  background: transparent;
  border: 1px solid rgba(243, 245, 240, 0.55);
  border-radius: var(--r-control);
  cursor: pointer;
}

.g-theme:focus-visible {
  outline: 2px solid var(--arancio);
  outline-offset: 3px;
}

@media (hover: hover) {
  .g-theme:hover:not(:disabled) {
    background: rgba(243, 245, 240, 0.08);
  }
}

/* The icon is the preference in force, drawn from the same attribute the palette reads. */
.g-theme__icon {
  width: 1.125rem;
  height: 1.125rem;
  background: currentColor;
  -webkit-mask: url("/web/brand/tema/chiaro.svg") center / contain no-repeat;
  mask: url("/web/brand/tema/chiaro.svg") center / contain no-repeat;
}

html[data-theme="scuro"] .g-theme__icon {
  -webkit-mask-image: url("/web/brand/tema/scuro.svg");
  mask-image: url("/web/brand/tema/scuro.svg");
}

html[data-theme="sistema"] .g-theme__icon {
  -webkit-mask-image: url("/web/brand/tema/sistema.svg");
  mask-image: url("/web/brand/tema/sistema.svg");
}

.g-login-brand img {
  content: url("/web/brand/mark-solid.svg");
}

html[data-theme="scuro"] .g-login-brand img {
  content: url("/web/brand/mark-solid-dark.svg");
}

@media (prefers-color-scheme: dark) {
  html[data-theme="sistema"] .g-login-brand img {
    content: url("/web/brand/mark-solid-dark.svg");
  }
}

.g-menu-toggle,
.g-mobile-menu {
  display: none;
}

/* Content: body padding from design system */
.g-content {
  flex: 1;
  width: 100%;
  max-width: var(--content-max);
  margin: 0 auto;
  padding: var(--pad-page-y) var(--pad-page-x) var(--pad-page-bottom);
  min-height: 0;
  /* Avoid iOS zoom quirks on focused inputs */
  -webkit-text-size-adjust: 100%;
  /* Focus target after multipage nav (a11y) — no outline until keyboard */
  outline: none;
}

.g-content:focus-visible {
  outline: 2px solid var(--arancio);
  outline-offset: 2px;
}

/* Login: centre the card in the available column — only when the login is what the session
   shows. Keyed on `[hidden]` alone it also matched the authed first paint, where CSS hides the
   card but the attribute is not there yet: the app panel was painted centred and jumped to the
   top once `bootSession` set `hidden` (first-paint-stability.spec.js). */
body:not([data-session="authed"]) .g-content:has(> .g-panel--login:not([hidden])) {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: stretch;
  padding-top: var(--s6);
  padding-bottom: max(var(--s6), env(safe-area-inset-bottom, 0px));
  /* The topbar is not painted outside a session, so the column is the whole viewport. */
  min-height: 100dvh;
}

/* Skip link — keyboard users past the 232px sidebar */
.g-skip {
  position: absolute;
  left: var(--s3);
  top: var(--s3);
  z-index: 100;
  padding: var(--s2) var(--s3);
  background: var(--verde);
  color: #f3f5f0;
  border-radius: var(--r-control);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform var(--motion-fast) var(--ease-standard);
}

.g-skip:focus {
  transform: translateY(0);
  outline: 2px solid var(--arancio);
  outline-offset: 2px;
  /* The paper ring under the orange one keeps the outline legible on the verde fill. */
  box-shadow: 0 0 0 2px var(--foglio);
}

/* Chips need ~280px; below this they wrap Esci onto a second row. */
@media (max-width: 1180px) {
  .g-topbar__roles {
    display: none;
  }
}

/* —— ≤1023px: one compact chrome row (design-system) —— */
@media (max-width: 1023px) {
  .g-app {
    flex-direction: column;
  }

  .g-sidebar {
    display: none;
  }

  .g-topbar__brand {
    display: flex;
    align-items: center;
    gap: var(--s2);
    flex-shrink: 0;
    color: #f3f5f0;
    text-decoration: none;
  }

  .g-topbar__brand img {
    width: 28px;
    height: 28px;
  }

  .g-topbar__brand .g-sidebar__name {
    color: inherit;
    font-size: var(--fs-13);
  }

  .g-topbar__brand:focus-visible {
    outline: 2px solid var(--arancio);
    outline-offset: 2px;
  }

  .g-topbar {
    position: sticky;
    top: 0;
    padding-top: 0;
  }

  .g-content {
    --pad-page-x: var(--s4);
    --pad-page-y: var(--s4);
    --pad-page-bottom: var(--s6);
    padding: var(--pad-page-y) var(--pad-page-x) var(--pad-page-bottom);
  }

  body:not([data-session="authed"]) .g-content:has(> .g-panel--login:not([hidden])) {
    padding-top: var(--s5);
  }
}

/* —— ≤859px: denser pad (design-system: 16px under 860px) —— */
@media (max-width: 859px) {
  .g-content {
    --pad-page-x: var(--s4);
    --pad-page-y: var(--s4);
  }

  .g-topbar {
    padding-left: var(--s4);
    padding-right: var(--s4);
  }

  .g-theme {
    width: var(--touch-min);
    height: var(--touch-min);
  }
}

/* —— ≤1023px: compact/tablet navigation drawer —— */
@media (max-width: 1023px) {
  .g-menu-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 var(--touch-min);
    width: var(--touch-min);
    height: var(--touch-min);
    padding: var(--s2);
    border: 1px solid rgba(243, 245, 240, 0.32);
    border-radius: var(--r-control);
    background: transparent;
    color: #f3f5f0;
    cursor: pointer;
  }

  .g-menu-toggle span {
    display: block;
    width: 1.15rem;
    height: 2px;
    margin: 2px 0;
    background: currentColor;
  }

  .g-menu-toggle:focus-visible {
    outline: 2px solid var(--arancio);
    outline-offset: 2px;
  }

  .g-mobile-menu[open] {
    display: flex;
    flex-direction: column;
    inset: 0 auto 0 0;
    width: min(88vw, 22rem);
    height: 100dvh;
    max-height: none;
    margin: 0;
    padding: max(var(--s4), env(safe-area-inset-top, 0px)) var(--s3)
      max(var(--s4), env(safe-area-inset-bottom, 0px));
    border: 0;
    border-right: 1px solid var(--bordo);
    background: var(--fondo-app);
    color: var(--ink);
    box-shadow: 0 0 2rem rgba(32, 40, 43, 0.2);
  }

  .g-mobile-menu::backdrop {
    background: rgba(32, 40, 43, 0.48);
  }

  .g-mobile-menu__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s3);
    padding: 0 var(--s2) var(--s3);
    border-bottom: 1px solid var(--bordo);
  }

  .g-mobile-menu__head h2 {
    margin: 0;
    font-size: var(--fs-20);
  }

  .g-mobile-menu__close {
    width: var(--touch-min);
    height: var(--touch-min);
    border: 1px solid var(--bordo);
    border-radius: var(--r-control);
    background: var(--foglio);
    color: var(--ink);
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
  }

  .g-mobile-menu__close:focus-visible {
    outline: 2px solid var(--arancio);
    outline-offset: 2px;
  }

  .g-mobile-menu__nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
    overflow-y: auto;
    padding: var(--s3) 0;
  }

  .g-mobile-menu__nav .g-sidebar__kicker {
    margin-top: var(--s4);
  }

  .g-mobile-menu__nav .g-sidebar__kicker:first-child {
    margin-top: var(--s1);
  }

  .g-mobile-menu__nav a {
    display: flex;
    align-items: center;
    min-height: var(--touch-min);
    padding: 0.5rem var(--s3);
    border: 1px solid transparent;
    border-radius: var(--r-control);
    color: var(--ink);
    text-decoration: none;
    font-size: var(--fs-15);
    font-weight: 500;
  }

  /* The drawer has room for honest labels; short labels belong to the scrolling bar. */
  .g-mobile-menu__nav a .g-sidebar__label {
    display: inline;
  }

  .g-mobile-menu__nav a .g-sidebar__label-short {
    display: none;
  }

  .g-mobile-menu__nav a[aria-current="page"] {
    background: var(--foglio);
    border-color: var(--bordo);
    color: var(--verde);
    font-weight: 700;
  }

  .g-mobile-menu__nav a:focus-visible {
    outline: 2px solid var(--arancio);
    outline-offset: 1px;
  }

  body.g-mobile-menu-open {
    overflow: hidden;
  }
}

/* —— ≤640px: phone / 375px signing surface —— */
@media (max-width: 640px) {

  .g-topbar {
    padding-left: var(--s3);
    padding-right: var(--s3);
    gap: var(--s2);
  }

  .g-topbar__user {
    gap: var(--s2);
  }

  .g-topbar__name {
    max-width: 8rem;
  }

  .g-topbar__org {
    display: none;
  }


  .g-content {
    --pad-page-x: var(--s3);
    --pad-page-y: var(--s3);
    --pad-page-bottom: max(var(--s6), env(safe-area-inset-bottom, 0px));
    padding: var(--pad-page-y) var(--pad-page-x) var(--pad-page-bottom);
  }
}

/* Landscape phone: keep chrome compact */
@media (max-width: 896px) and (max-height: 420px) and (orientation: landscape) {
  .g-sidebar__brand {
    display: none;
  }

  .g-sidebar__nav {
    padding-top: var(--s1);
    padding-bottom: var(--s1);
  }

  body:not([data-session="authed"]) .g-content:has(> .g-panel--login:not([hidden])) {
    padding-top: var(--s3);
    padding-bottom: var(--s3);
  }
}

/* State rules follow component display rules so they win without !important. */
body:not([data-session="authed"]) .g-sidebar,
body:not([data-session="authed"]) .g-topbar,
body[data-session="pending"] #panel-login,
body[data-session="authed"] #panel-login,
.g-sidebar__nav a[hidden] {
  display: none;
}

body:not([data-session="authed"]) :where(.g-content) {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: stretch;
  padding: var(--s6) var(--s4);
}

/* Chrome is the same element across product pages. The views are not:
   naming `.g-content` crossfades Coda onto Cabina (two pages stacked). */
html:active-view-transition-type(groma-out-app):active-view-transition-type(groma-in-app) .g-sidebar {
  view-transition-name: g-sidebar;
}

html:active-view-transition-type(groma-out-app):active-view-transition-type(groma-in-app) .g-topbar {
  view-transition-name: g-topbar;
}

@keyframes g-vt-out {
  to {
    opacity: 0;
  }
}

@keyframes g-vt-in {
  from {
    opacity: 0;
  }
}

/* Exit, then enter — a simultaneous crossfade is two UIs in the same frame. */
::view-transition-old(root) {
  animation: var(--motion-fast) ease-out both g-vt-out;
}

::view-transition-new(root) {
  animation: var(--motion-fast) ease-in var(--motion-fast) both g-vt-in;
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none;
  }
}
