/* Sign-in control and app launcher.
 *
 * Kept out of style.css on purpose: that file is the scroll
 * choreography and is delicate. Nothing here touches the timeline. */

/* The header's nav holds the links, the burger and now the auth
 * control. Above the breakpoint the burger is hidden, below it the
 * link list is, so at most two children are ever visible - but the
 * auth control shows at every width, which is why nav has to lay out
 * as a row. */
header nav {
   display: flex;
   align-items: center;
   gap: 1rem 2rem;

   /* At 375 the wordmark, the auth pill and the burger come to about
    * 311px against 300px of content width, and since the wordmark is
    * no longer allowed to absorb that, the gap has to give instead. */
   @media (width < 30rem) {
      column-gap: 1rem;
   }
}

/* The logo is the one thing that must not give: as a flex item it
 * would otherwise be the first to shrink once the row got tight,
 * and a squashed wordmark reads as a bug rather than as a
 * responsive layout. */
header .logo,
header > div > :any-link:has(img) {
   flex: none;
}

/* Below ~360px even a fixed-gap row runs out: 9rem of wordmark plus
 * the pill plus the burger is 295px against 256px of content. The
 * wordmark is the only item with slack, and at that width it is
 * oversized anyway. */
@media (width < 22.5rem) {
   header img { inline-size: 6.5rem; }
}

/* Likewise the link labels: "Focus Areas" breaking over two lines
 * silently grows the whole fixed header, which then covers more of
 * the hero than the scroll choreography allows for. */
header nav > ul :any-link {
   white-space: nowrap;
}

/* The legal pages and the launcher have no burger to collapse into,
 * so their header row wraps instead - at 375 the two German legal
 * labels plus the auth pill simply do not fit beside the wordmark.
 * `:has(.menu)` is what distinguishes them from the homepage header,
 * which collapses rather than wraps. */
header:not(:has(.menu)) {
   > div { flex-wrap: wrap; }
   nav { flex-wrap: wrap; }
}

/* The header now carries one item more than it was designed for, and
 * the original 48rem hand-off from burger to full link list no longer
 * has the room for it: measured, the row overflows its own gutters by
 * 52px at 768 and still by 1px at 832, only clearing from ~864 up.
 * So the burger stays a little longer. Both rules have to be restated
 * because style.css scopes them to `width < 48rem`. */
@media (48rem <= width < 62rem) {
   header nav > ul { display: none; }
   header .menu { display: block; }
}

/* Once the list is back, it has to share the row with the auth pill.
 * The original fixed 2.5rem between links only fits from ~1280 up
 * now; letting it breathe with the viewport buys back the ~70px that
 * makes 992 work, and it still reaches the original spacing on a
 * wide screen. */
header nav > ul {
   gap: clamp(1.25rem, 2.2vw, 2.5rem);
}

/* Language switch (EN/DE).
 *
 * On the homepages the link list decides how much room the row has: the English list already fills it to ~1000px
 * and the German labels are wider still. So beside the list the switch only shows from 78rem up; below that it
 * sits in the burger menu and the footer. The legal and system pages wrap their header instead of collapsing it,
 * so there it always shows. */
header nav > .lang {
   color: inherit;
   text-decoration: none;
   font-size: .95rem;
   font-weight: 300;
   letter-spacing: .08em;
   white-space: nowrap;
}

header nav > .lang:hover { text-decoration: underline; }

header:has(.menu) nav > .lang { display: none; }

@media (width >= 78rem) {
   header:has(.menu) nav > .lang { display: inline; }
}

/* German labels are longer ("Handlungsfelder", "Über uns"): the link list needs about 70px more than the English
 * one, so the German homepage keeps the burger until 72rem instead of 62rem. */
@media (62rem <= width < 72rem) {
   html:lang(de) header nav > ul { display: none; }
   html:lang(de) header .menu { display: block; }
}

/* Signed in, this holds the app switcher and the avatar, which sit
 * as a pair the way Google sets them; signed out, only the Log in pill
 * shows, so the gap never applies to it. */
.auth {
   display: flex;
   align-items: center;
   gap: .5rem;
}

/* Same pill as the product popups' Visit button, so the header does
 * not introduce a third button language. */
.auth__btn {
   color: inherit;
   text-decoration: none;
   border: 1px solid currentColor;
   border-radius: 1.5rem;
   padding: .45rem 1.1rem;
   font-size: .95rem;
   font-weight: 300;
   white-space: nowrap;
   transition: background-color .33s, color .33s, border-color .33s;

   @media (width < 30rem) {
      padding-inline: .85rem;
      font-size: .9rem;
   }

   &:hover {
      background: rgb(0 72 90);
      border-color: transparent;
      color: #fff;
   }
}

/* Holds the suite's avatar and account menu (js/suite.js). */
.auth__user {
   display: flex;
   align-items: center;
}


/* ---------------------------------------------------------------- */
/* Launcher page                                                     */

/* The launcher is a <main> inside the subpage shell, so it inherits
 * that page's 10vw gutters and its 1fr row. It opts out of the 75ch
 * measure meant for legal prose; the one-line states (loading,
 * redirect, empty, error) sit centred in whatever height is left over,
 * the app list starts at the top. */
.launcher {
   max-inline-size: none;
   display: grid;
   align-content: center;
   padding-block: 4rem 6rem;

   &[data-state="apps"] {
      align-content: start;
      max-inline-size: 76rem;
      padding-block: clamp(2.5rem, 7vh, 4.5rem) 5rem;
   }
}

/* A plain warm paper, set on the page rather than on .launcher so the
 * header and footer sit on the same surface instead of framing it. The
 * subpage shell paints both of those white, hence the second rule. */
body:has(.launcher) {
   background: #f6f4f1;
}

body:has(.launcher) :is(header, footer) {
   background: transparent;
}

.launcher h2 {
   font-size: clamp(2.25rem, 5vw, 4rem);
   line-height: 1;
   letter-spacing: -.1rem;
   font-weight: 300;
   margin: 0 0 .75rem;
}

.launcher__meta {
   font-size: .85rem;
   font-weight: 300;
   letter-spacing: .2em;
   text-transform: uppercase;
   opacity: .7;
   margin: 0 0 2.5rem;
}

.launcher p {
   font-size: 1.1rem;
   line-height: 1.5;
   max-inline-size: 42rem;
}

/* The list's own heading is a greeting, not a statement, so it gets
 * less of the page than the one-line states do. */
.launcher__head {
   h2 {
      font-size: clamp(2rem, 3.6vw, 3rem);
      letter-spacing: -.06rem;
      margin-block-end: .6rem;
   }

   .launcher__meta {
      font-size: .78rem;
      letter-spacing: .14em;
      margin-block-end: clamp(2rem, 5vh, 3rem);
   }
}

/* One panel at a time, chosen by the state auth.js writes onto the
 * container. Everything is hidden until then, so no panel flashes
 * while Clerk is still deciding whether there is a session. */
[data-launcher] [data-panel] { display: none; }
[data-launcher][data-state="loading"] [data-panel="loading"],
[data-launcher][data-state="apps"] [data-panel="apps"],
[data-launcher][data-state="redirect"] [data-panel="redirect"],
[data-launcher][data-state="empty"] [data-panel="empty"],
[data-launcher][data-state="error"] [data-panel="error"] { display: block; }

.launcher__group + .launcher__group {
   margin-block-start: 2.25rem;
}

/* Shelf label with a hairline running out to the gutter. */
.launcher__label {
   display: flex;
   align-items: center;
   gap: 1rem;
   margin: 0 0 .9rem;
   font-size: .72rem;
   font-weight: 400;
   letter-spacing: .2em;
   text-transform: uppercase;
   color: rgb(24 18 19 / .55);

   &::after {
      content: "";
      flex: 1;
      border-block-start: 1px solid rgb(24 18 19 / .12);
   }
}

.launcher__grid {
   display: grid;
   grid-template-columns: repeat(auto-fill, minmax(min(19rem, 100%), 1fr));
   gap: .75rem;
}

/* Icon, name and blurb, chevron: a compact row, so the whole suite
 * fits on one screen instead of the first two rows of it. */
.app-tile {
   display: grid;
   grid-template-columns: auto 1fr auto;
   align-items: center;
   gap: 1rem;
   padding: 1.1rem 1.15rem 1.1rem 1.1rem;
   background: #fff;
   border: 1px solid rgb(24 18 19 / .09);
   border-radius: .8rem;
   color: inherit;
   text-decoration: none;
   transition: border-color .2s, box-shadow .2s, transform .2s;

   &:hover {
      border-color: rgb(24 18 19 / .3);
      box-shadow: 0 1px 2px rgb(24 18 19 / .04), 0 10px 24px rgb(24 18 19 / .07);
      transform: translateY(-1px);
   }

   &:focus-visible {
      outline: 2px solid rgb(0 72 90);
      outline-offset: 3px;
   }

   .rr42-icon {
      inline-size: 2.75rem;
      block-size: 2.75rem;
   }

   /* `backwards`, not `both`: a fill that outlived the entrance would
    * keep overriding the hover lift's transform for good. */
   @media (prefers-reduced-motion: no-preference) {
      animation: rise-in .5s cubic-bezier(.2, .7, .3, 1) backwards;
      animation-delay: calc(var(--i, 0) * 45ms);

      .rr42-icon {
         animation: rr42-icon-in .6s cubic-bezier(.3, 1.5, .5, 1) backwards;
         animation-delay: calc(var(--i, 0) * 45ms + 120ms);
      }
   }
}

.app-tile__text {
   display: grid;
   gap: .1rem;
   min-inline-size: 0;

   strong {
      font-size: 1.1rem;
      font-weight: 400;
      line-height: 1.25;
   }

   span {
      font-size: .9rem;
      line-height: 1.35;
      color: rgb(24 18 19 / .62);
   }
}

.app-tile__go {
   inline-size: 1.1rem;
   block-size: 1.1rem;
   fill: none;
   stroke: currentColor;
   stroke-width: 1.6;
   stroke-linecap: round;
   stroke-linejoin: round;
   opacity: .25;
   transition: opacity .2s, transform .2s;
}

.app-tile:hover .app-tile__go {
   opacity: .9;
   transform: translateX(2px);
}

/* A tile settling into place on load. */
@keyframes rise-in { from { opacity: 0; transform: translateY(10px); } }

/* Search hides tiles and empty shelves; their author `display` would
 * otherwise outrank the browser's own [hidden] rule. */
.app-tile[hidden],
.launcher__group[hidden] { display: none; }

.launcher__nothing {
   margin: 0;
   color: rgb(24 18 19 / .62);
}

/* Phones get Google's launcher grid instead of the list: three across,
 * icon over name, no blurb. With icons that carry this much on their
 * own, all nine apps fit on the first screen. */
@media (width < 30rem) {
   .launcher__grid {
      grid-template-columns: repeat(3, 1fr);
      grid-auto-rows: 1fr;
      gap: .5rem;
   }

   .app-tile {
      grid-template-columns: 1fr;
      justify-items: center;
      align-content: start;
      gap: .55rem;
      padding: 1rem .25rem .8rem;
      text-align: center;

      .rr42-icon {
         inline-size: 2.6rem;
         block-size: 2.6rem;
      }
   }

   .app-tile__text {
      strong {
         font-size: .88rem;
         line-height: 1.2;
         text-wrap: balance;
      }

      span { display: none; }
   }

   .app-tile__go { display: none; }
}

.launcher__note {
   margin-block-start: 2rem;
   font-size: .95rem;
   opacity: .75;
}

.launcher :any-link.launcher__link {
   color: inherit;
   text-decoration: none;
   border-bottom: 1px solid currentColor;
   padding-block-end: .15rem;

   &:hover { opacity: .7; }
}

@media (prefers-reduced-motion: reduce) {
   .auth__btn,
   .app-tile,
   .app-tile__go { transition: none; }

   .app-tile:hover,
   .app-tile:hover .app-tile__go { transform: none; }
}
