/* ============================================================================
   App launcher — two-pane
   ----------------------------------------------------------------------------
   Replaces _AppSwitcherMegaMenu. The menu it replaces rendered every screen of
   every app into the DOM of every page, opened its three levels on :hover only
   (so it was unreachable on touch), and coloured its tiles by id % 6.

   Every colour here comes from gimcore-tokens.css, so a tenant that redefines
   --gs-brand gets a launcher in its own brand, and dark mode follows.
   ============================================================================ */

.gs-launcher-parent { position: static !important }

/* Colour deliberately not set here: the button carries .nav-link so the navbar
   theme owns it. Padding is reset because .nav-link brings its own. */
.gs-lbtn {
  width: 34px; height: 34px; flex: none; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: 6px; background: transparent; cursor: pointer;
}
/* Derived from the text colour, so it reads on a dark navbar and on a light one
   rather than assuming white. */
.gs-lbtn:hover, .gs-lbtn[aria-expanded="true"] {
  background: color-mix(in srgb, currentColor 15%, transparent);
}
@supports not (background: color-mix(in srgb, red, blue)) {
  .gs-lbtn:hover, .gs-lbtn[aria-expanded="true"] { background: rgba(127, 127, 127, .22) }
}
.gs-lbtn:focus-visible { outline: 2px solid currentColor; outline-offset: 1px }
.gs-lbtn .bi { font-size: 20px; line-height: 1 }

.gs-scrim { position: fixed; inset: 0; z-index: 1090; display: none }
.gs-scrim.gs-open { display: block }

.gs-launcher {
  position: absolute; z-index: 1100; top: 100%; left: 8px; margin-top: 6px;
  /* 800px was narrower than the menu this replaces (which went to 1000px), which
     left roughly 280px per column once the rail was taken out — not enough for an
     app name and a description side by side. Not full width either: a panel that
     spans the viewport is a mega menu again, covering the work underneath, which
     was the complaint that started this. */
  width: min(1080px, calc(100vw - 24px));
  background: var(--gs-surface); border: 1px solid var(--gs-line); border-radius: 12px;
  box-shadow: 0 1px 3px rgba(15, 23, 41, .07), 0 16px 40px -12px rgba(15, 23, 41, .22);
  display: none; overflow: hidden;
}
.gs-launcher.gs-open { display: flex; flex-direction: column }

/* ── search ───────────────────────────────────────────────────────────────── */
.gs-lsearch {
  display: flex; align-items: center; gap: 9px; padding: 0 14px; height: 48px;
  border-bottom: 1px solid var(--gs-line); flex: none;
}
.gs-lsearch .bi { color: var(--gs-ink-3); flex: none }
.gs-lsearch input {
  flex: 1; min-width: 0; border: 0; outline: 0; background: transparent;
  font-size: 13.5px; color: var(--gs-ink);
}
.gs-lsearch input::placeholder { color: var(--gs-ink-3) }
.gs-kbd {
  font-size: 10px; color: var(--gs-ink-3); background: var(--gs-surface-3);
  border: 1px solid var(--gs-line); border-radius: 4px; padding: 1px 5px; line-height: 1.6;
}
.gs-closex { display: none; border: 0; background: transparent; color: var(--gs-ink-3); cursor: pointer; padding: 4px }

/* ── the two panes ────────────────────────────────────────────────────────────
   Both columns are the same shape: a 56px header band on one baseline, then a
   flexing list. That is what makes the 1px rule run unbroken across the panel
   instead of stopping at the divider. */
/* 480 rather than 436: with two columns and the headings hidden, fifteen apps came
   to 50px more than the pane could hold, which is a scrollbar for one row. The rail
   needs about 320px, so the extra height costs nothing there. */
.gs-lwrap { display: flex; height: 480px; min-height: 0 }

.gs-railcol {
  width: 214px; flex: none; border-right: 1px solid var(--gs-line);
  background: var(--gs-surface-2); display: flex; flex-direction: column; min-height: 0;
}
.gs-railhead, .gs-phead {
  height: 56px; flex: none; border-bottom: 1px solid var(--gs-line);
  display: flex; align-items: center; gap: 10px; padding: 0 14px;
}
.gs-railhead .gs-t, .gs-phead .gs-t {
  font-size: 14px; font-weight: 600; margin: 0; line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gs-railhead .gs-d, .gs-phead .gs-d {
  font-size: 11.5px; color: var(--gs-ink-3); margin: 1px 0 0; line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gs-railhead .gs-tx, .gs-phead .gs-tx { min-width: 0 }

.gs-rail { flex: 1; min-height: 0; overflow-y: auto; padding: 6px; display: flex; flex-direction: column; gap: 1px }
.gs-rail-label {
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--gs-ink-3); padding: 9px 9px 4px; flex: none;
}
/* 13.5px, not 12.5: the rail is a primary navigation list read at a glance, and it
   was set a full point smaller than the app rows it selects. The row grows with it
   so the text is not squeezed against its own bounds. */
.gs-ritem {
  display: flex; align-items: center; gap: 10px; height: 31px; padding: 0 9px;
  border-radius: 6px; cursor: pointer; font-size: 13.5px; color: var(--gs-ink-2);
  position: relative; flex: none; text-decoration: none;
}
.gs-ritem:hover { background: var(--gs-surface-3) }
.gs-ritem.gs-on { background: color-mix(in srgb, var(--gs-brand) 9%, transparent); color: var(--gs-brand); font-weight: 600 }
.gs-ritem.gs-on::before {
  content: ""; position: absolute; left: -6px; top: 4px; bottom: 4px; width: 2.5px;
  border-radius: 0 3px 3px 0; background: var(--gs-brand);
}
/* every marker in the same 16px box, so all rail labels share one left edge */
.gs-ritem .gs-gi { width: 16px; flex: none; display: flex; align-items: center; justify-content: center }
.gs-ritem .gs-dot { width: 8px; height: 8px; border-radius: 2px; background: currentColor }
.gs-ritem .gs-lb { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.gs-ritem .gs-cnt { margin-left: auto; font-size: 11.5px; color: var(--gs-ink-3); font-variant-numeric: tabular-nums; flex: none }
.gs-ritem.gs-on .gs-cnt { color: var(--gs-brand) }
.gs-ritem .gs-chev { display: none; margin-left: auto; color: var(--gs-ink-3); flex: none }

.gs-pane { flex: 1; min-width: 0; display: flex; flex-direction: column }
.gs-backb {
  display: none; border: 1px solid var(--gs-line); background: var(--gs-surface);
  border-radius: 6px; padding: 4px 6px; cursor: pointer; color: var(--gs-ink-2); flex: none;
}
/* overflow-x hidden as a backstop: nothing here should ever scroll sideways, and a
   horizontal scrollbar is always a layout bug rather than a legitimate state. */
.gs-plist { padding: 6px 8px; overflow-y: auto; overflow-x: hidden; flex: 1; min-height: 0 }

/* Two columns for the All view only.
   One column of 58px rows shows about five of fifteen apps before scrolling, which
   is the one thing the mega menu did better — it spread everything across four
   columns and you saw the lot. Two columns roughly doubles what is visible while
   keeping the description, which the old menu never had room for.
   Group headings span both columns so the categories still read as bands. */
.gs-plist.gs-two-col {
  display: grid;
  /* minmax(0, 1fr), not 1fr. A bare 1fr is minmax(auto, 1fr), and auto takes its
     minimum from the content — so one 120-character description with nowrap on it
     forced its track wider than half the pane, pushed the second column off to the
     right and produced a horizontal scrollbar. The ellipsis never got a chance
     because the track had already grown. minmax(0, …) lets the track be narrower
     than its content, which is what makes the truncation work. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 0 6px; align-content: start;
}
/* Group headings are dropped here, not styled smaller. Seven of them each take a
   full row, so they ate most of what the second column gained — measured, the
   overflow only fell from 636px to 376px with them in. Category is still legible
   two other ways: the rail names it, and the tile colour encodes it. Apps stay
   sorted by category so the colours still arrive in blocks. */
.gs-plist.gs-two-col .gs-slabel { display: none }
.gs-plist.gs-two-col .gs-arow { min-height: 50px; padding: 6px 10px }
/* The count button is the first thing to go when space is tight: it is a
   drill-down affordance, and the category views keep it. */
.gs-plist.gs-two-col .gs-meta { display: none }
@media (max-width: 820px) {
  .gs-plist.gs-two-col { grid-template-columns: 1fr }
  .gs-plist.gs-two-col .gs-meta { display: flex }
}

/* ── rows ─────────────────────────────────────────────────────────────────── */
.gs-arow {
  display: flex; align-items: center; gap: 12px; min-height: 58px; padding: 8px 10px;
  border-radius: 6px; cursor: pointer; text-decoration: none; color: var(--gs-ink); position: relative;
}
.gs-arow:hover { background: var(--gs-surface-3) }
.gs-arow.gs-sel { background: color-mix(in srgb, var(--gs-brand) 9%, transparent) }
.gs-arow.gs-sel::before {
  content: ""; position: absolute; left: 0; top: 6px; bottom: 6px; width: 2.5px;
  border-radius: 0 3px 3px 0; background: var(--gs-brand);
}
/* title and description are block level: as inline spans they ran together */
.gs-arow .gs-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px }
/* 600 and a darker secondary: at 500 against #8792a5 the rows had no hierarchy and
   the panel read as uniformly faint. */
.gs-arow .gs-t {
  display: block; font-size: 13.5px; font-weight: 600; line-height: 1.3;
  letter-spacing: -.005em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gs-arow .gs-d {
  display: block; font-size: 11.5px; color: var(--gs-ink-2); line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gs-arow .gs-star {
  width: 24px; height: 24px; border: 0; background: transparent; color: var(--gs-ink-3);
  border-radius: 5px; cursor: pointer; opacity: 0; flex: none;
  display: flex; align-items: center; justify-content: center;
}
.gs-arow:hover .gs-star, .gs-arow .gs-star.gs-on, .gs-arow.gs-sel .gs-star { opacity: 1 }
.gs-arow .gs-star.gs-on { color: var(--gs-cat-7) }

/* the view count doubles as the drill-down control: it states the cost of
   looking inside, and clicking it is how you look */
.gs-arow .gs-meta {
  display: flex; align-items: center; gap: 3px; font-size: 11px; color: var(--gs-ink-3);
  flex: none; font-variant-numeric: tabular-nums; white-space: nowrap;
  border: 1px solid transparent; border-radius: 20px; padding: 3px 6px 3px 9px;
  background: transparent; cursor: pointer;
}
.gs-arow .gs-meta:hover { background: var(--gs-surface); border-color: var(--gs-line); color: var(--gs-ink-2) }
.gs-arow.gs-srow .gs-meta { cursor: default; padding-right: 9px }
.gs-arow.gs-srow .gs-meta:hover { background: transparent; border-color: transparent; color: var(--gs-ink-3) }
.gs-arow.gs-child { padding-left: 34px }

/* The tile carries the category colour class, so both the glyph and a soft wash of
   the same hue come from currentColor. A flat grey square for every app read as an
   empty placeholder and made the whole panel look weightless; the menu this replaces
   was wrong about WHICH colour to use, not about using one. */
/* ── Two densities, one colour system ────────────────────────────────────────
   .gs-tile      — comfortable. A tinted square behind the glyph. For surfaces
                   where you are CHOOSING between many different things and the
                   rows are tall enough to carry it: the launcher, All apps, the
                   project list.
   .gs-nav-icon  — compact. The glyph alone. For dense navigation: dropdown menus
                   and the report rail, where rows are around 32px and thirty
                   tinted squares in a column would read as noise rather than as
                   structure.

   Both take their colour from the same gs-ic-* class, so the two densities are
   the same system seen at two sizes — not two systems.
   ────────────────────────────────────────────────────────────────────────── */
.gs-tile {
  width: 34px; height: 34px; border-radius: 9px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, currentColor 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 12%, transparent);
}
.gs-nav-icon {
  width: 18px; flex: none; display: inline-flex; align-items: center;
  justify-content: center; margin-right: 10px;
}
.gs-nav-icon .bi, i.gs-nav-icon { font-size: 15px; line-height: 1 }

/* The dropdown rows sat almost against the panel edge — the icon started at 8px,
   which reads as a rendering slip rather than as a margin. 14px matches the header
   band in the launcher, so the two menus line up. */
.project-mega-menu .app-item-link { padding-left: 14px !important; padding-right: 14px !important }
.project-mega-menu { padding: 14px 10px !important }
.navbar .dropdown-menu .dropdown-item.gt-p-l-5 { padding-left: 14px !important }

/* The Add menu carries the screen's own icon rather than a column of identical plus
   signs: the menu is already titled "Add", so repeating that once per row identified
   nothing. A small plus badge keeps the action legible on each row. */
.gs-nav-icon.gs-add { position: relative }
.gs-nav-icon.gs-add::after {
  content: "+";
  position: absolute; right: -5px; bottom: -4px;
  font-size: 11px; font-weight: 700; line-height: 1;
  color: var(--gs-brand);
  background: var(--gs-surface);
  border-radius: 50%; padding: 0 2px;
}
/* The tile owns its interior, whatever else is on the page.
   Two things make that necessary rather than defensive clutter: the product injects
   company.Css straight from the database on every page, which cannot be read or
   searched from here, and the legacy sidebar CSS already sized a bare <i> to 44px
   so the glyph itself formed the left gutter. A component whose geometry depends on
   ambient rules will keep breaking in places nobody thought to check. */
/* Padding, not clipping, is what keeps the glyph inside.
   The first attempt used overflow:hidden alone, which stopped the spill by cutting
   the glyph off at the edge — the icon then looked shaved and pressed against the
   side. A border-box inset gives the glyph a smaller area to live in, so it never
   reaches the edge in the first place; overflow stays only as a last resort for
   anything ambient CSS does that this cannot anticipate. */
.gs-tile { box-sizing: border-box; padding: 4px; overflow: hidden }
.gs-tile > .bi,
.gs-tile > i {
  width: auto !important; height: auto !important;
  min-width: 0; max-width: 100%;
  line-height: 1 !important; text-align: center;
  transform: none;
}

/* Glyph at roughly half the tile. Bootstrap Icons fill their em box almost edge to
   edge, so a glyph sized much above half looks cramped even before it touches. */
.gs-tile > .bi { font-size: 17px !important; color: currentColor }

.gs-tile.gs-sm { width: 28px; height: 28px; border-radius: 7px; padding: 4px }
.gs-tile.gs-sm > .bi { font-size: 14px !important }

/* Dense navigation gets the same tile, just smaller. The first attempt dropped the
   tile entirely in menus on the theory that thirty tinted squares would be noise;
   shown both, the reviewer preferred the tile, and side by side it does read as the
   more finished of the two. One treatment everywhere, three sizes. */
.gs-tile.gs-xs { width: 24px; height: 24px; border-radius: 6px; margin-right: 10px; padding: 3px }
.gs-tile.gs-xs > .bi { font-size: 12px !important }

.gs-tile img { width: 17px; height: 17px; object-fit: contain }

@supports not (background: color-mix(in srgb, red, blue)) {
  .gs-tile { background: var(--gs-surface-3); box-shadow: none }
}

.gs-slabel {
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--gs-ink-3); padding: 11px 9px 5px;
}
.gs-empty { padding: 40px 16px; text-align: center; color: var(--gs-ink-3); font-size: 12.5px }
.gs-empty b { display: block; color: var(--gs-ink-2); font-size: 13.5px; margin-bottom: 3px }
.gs-launcher mark { background: transparent; color: var(--gs-brand); font-weight: 700; padding: 0 }

.gs-lfoot {
  border-top: 1px solid var(--gs-line); background: var(--gs-surface-2); height: 38px;
  display: flex; align-items: center; gap: 12px; padding: 0 12px;
  font-size: 11.5px; color: var(--gs-ink-3); flex: none;
}
.gs-lfoot a { color: var(--gs-brand); text-decoration: none; font-weight: 600 }
.gs-lfoot .gs-sp { margin-left: auto }
.gs-lfoot .gs-keys { display: flex; gap: 10px; color: var(--gs-ink-3) }

/* ── small screens ────────────────────────────────────────────────────────────
   Full-screen sheet, and the two panes become a drill-down. The menu this
   replaces opened its submenus on :hover with no click handler, so on a touch
   device its screen level could not be reached at all. */
@media (max-width: 820px) {
  .gs-launcher { position: fixed; top: 0; left: 0; width: 100%; max-width: none; height: 100%;
                 margin-top: 0; border-radius: 0; border: 0 }
  .gs-lwrap { height: auto; flex: 1; min-height: 0 }
  .gs-closex { display: flex }
  .gs-kbd, .gs-lfoot .gs-keys { display: none }
  .gs-railcol { width: 100%; border-right: 0; background: var(--gs-surface) }
  .gs-ritem { height: 44px; padding: 0 12px; font-size: 14px }
  .gs-ritem .gs-chev { display: block }
  .gs-ritem .gs-cnt { margin-left: 0 }
  .gs-ritem.gs-on { background: transparent; color: var(--gs-ink-2); font-weight: 500 }
  .gs-ritem.gs-on::before { display: none }
  .gs-backb { display: flex }
  .gs-arow .gs-star { opacity: 1 }
  .gs-hide-rail .gs-railcol { display: none }
  .gs-hide-pane .gs-pane { display: none }
}

/* ── All apps page ────────────────────────────────────────────────────────── */
/* Capped rather than full bleed: on a wide monitor auto-fill produced seven columns
   of 258px cards, which is more thumbnails than anyone scans and leaves every name
   truncated. A ceiling keeps the cards readable and the page scannable. */
.gs-allapps { padding: 18px 4px 60px; max-width: 1560px }
.gs-aahead { display: flex; align-items: center; gap: 12px; margin-bottom: 14px }
.gs-aahead .gs-tx { flex: 1; min-width: 0 }
.gs-allapps h1 { font-size: 20px; margin: 0 0 2px; font-weight: 600 }
.gs-allapps .gs-sub { color: var(--gs-ink-3); font-size: 12.5px }
.gs-iconb {
  width: 34px; height: 34px; flex: none; border: 1px solid var(--gs-line);
  background: var(--gs-surface); border-radius: 6px; cursor: pointer; color: var(--gs-ink-2);
  display: flex; align-items: center; justify-content: center;
}
.gs-iconb:hover { background: var(--gs-surface-3); color: var(--gs-ink) }
.gs-aasearch {
  display: flex; align-items: center; gap: 9px; background: var(--gs-surface);
  border: 1px solid var(--gs-line); border-radius: 8px; padding: 0 13px; height: 42px;
  max-width: 520px; margin-bottom: 14px;
}
.gs-aasearch input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; font-size: 13.5px; color: var(--gs-ink) }
.gs-pills { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 16px }
.gs-pill {
  border: 1px solid var(--gs-line); background: var(--gs-surface); border-radius: 16px;
  padding: 4px 13px; font-size: 12px; cursor: pointer; white-space: nowrap; color: var(--gs-ink-2);
}
.gs-pill.gs-on { background: var(--gs-brand); border-color: var(--gs-brand); color: var(--gs-brand-fg) }
.gs-acat { margin-bottom: 20px }
.gs-acat h2 {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .09em;
  color: var(--gs-ink-3); margin: 0 0 8px; font-weight: 700;
}
/* minmax(0, …) inside the track as well, so a long description truncates instead of
   widening its own card — the same bug the launcher's two-column layout had. */
.gs-agrid {
  display: grid; gap: 8px;
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
}
.gs-acard {
  background: var(--gs-surface); border: 1px solid var(--gs-line); border-radius: 8px;
  padding: 11px 12px; display: flex; gap: 11px; align-items: center;
  cursor: pointer; text-decoration: none; color: var(--gs-ink);
}
/* text-decoration again on hover: the card sets none, but that is (0,1,0) and
   Bootstrap's a:hover is (0,1,1), so the underline came back the moment the pointer
   landed — on a card whose whole surface is the link, which reads as a glitch. */
.gs-acard:hover { border-color: var(--gs-brand); text-decoration: none }
.gs-acard .gs-tx { min-width: 0 }
.gs-acard .gs-t { display: block; font-size: 13px; font-weight: 600; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis }
.gs-acard .gs-d { display: block; font-size: 11.5px; color: var(--gs-ink-3); line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis }

/* color-mix is recent; without it the tint simply does not apply and the
   accent bar still marks the selection */
@supports not (color: color-mix(in srgb, red, blue)) {
  .gs-ritem.gs-on, .gs-arow.gs-sel { background: var(--gs-surface-3) }
}

/*  Underline on hover, put back by something else.

    app.min.css carries "a:not([class*=btn]):hover { text-decoration: underline }".
    :not() takes the specificity of its argument, so that attribute selector makes the
    rule (0,2,1) — and it is loaded after this file. A component rule of (0,2,0) loses
    outright and (0,2,1) loses the tie on source order, which is why setting
    text-decoration on .gs-acard:hover changed nothing. Naming the container as well
    makes these (0,3,1) and settles it without reaching for !important.

    Every anchor this stylesheet styles is listed. .gs-arow is a div and is not
    affected; .gs-lbtn and .gs-ip-icon are buttons. */
.gs-launcher a.gs-ritem:hover,
.gs-launcher .gs-lfoot a:hover,
.gs-allapps a.gs-acard:hover {
  text-decoration: none;
}
