/* Top bar -- design-handoffs/asportal-public/design-guide/Portal_Top.css,
   confirmed against its own .png. A fundamentally different component
   from admin's Top, not a reskin of it: admin's .topbar is a white bar
   carrying page-title+breadcrumb (no logo -- the logo lives in admin's
   sidebar instead); Portal's Top is a dark global masthead carrying the
   app logo directly, with real hamburger/tablet and logo-swap/control-
   dropping mobile behavior admin has zero equivalent of. Content
   layout/sizing below (60px height, 32px-tall right-side buttons) does
   match admin's Top numerically -- only the color scheme and logo
   placement differ.

   PC: logo (left) + 교육신청 / gildong(account) / 로그아웃 (right), each
   with its own Hover/Pressed fill (rgba(255,255,255,.25) over the dark
   bg -- var(--color-top-hover) can't reuse --color-surface-muted, a
   light-mode-only token that would be invisible here). 로그아웃 alone
   carries a translucent border at rest (.topbar-button-bordered); 교육신청/
   gildong have none until hovered, confirmed directly against the PNG
   (only 로그아웃 shows an outlined box in the "PC) Top - Menu" normal-state
   row).
   Tablet: adds a hamburger button before the logo (opens base/
   navigation.css's drawer, see nav-drawer.js) -- otherwise identical to
   PC.
   Mobile: hamburger + a *smaller* logo variant, and gildong/로그아웃 are
   dropped entirely from the bar -- the guide's own Navigation.png shows
   both relocated to the drawer's .sidebar-footer instead (nowhere else
   for them to go in the collapsed mobile bar). **교육신청 itself stays in
   the bar at real Mobile widths** -- confirmed directly against
   `design-handoffs/asportal-public/license status/M) Portal_패키지 현황.png`
   (360px canvas) and Portal_Navigation.png's own Mobile drawer-open mock,
   both show 교육신청 still visible top-right even with gildong/로그아웃
   gone and the drawer open. (An earlier pass moved 교육신청 into the drawer
   too, matching a real bug at pathologically narrow desktop-resize widths
   -- see the `<=249px` tier below -- but over-applied that fix to the
   whole `<=767px` Mobile tier, which doesn't match the design; corrected
   per explicit user clarification, see DEV_LOG 2026-07-21.)

   Logo: images/base/img-logo-wh.svg (127x30), already a solid #fff fill
   unlike admin's fixed dark-color logo so no recolor trick is needed.
   Renders at this same fixed size at every breakpoint including Mobile,
   by explicit decision (2026-08-04) overriding design-guide's own Mobile
   export, which shows a smaller/simplified wordmark there -- do not
   reintroduce a resize or an img-logo-small-wh.svg swap without
   confirming that decision has changed; same explicit call applies to
   .public-top-logo (public-top.css). img-logo.svg/img-logo-small-bl.svg
   (dark variants) also exist for any future light-background context,
   not used by this dark Top bar; img-logo-small-wh.svg is currently
   unused for the same reason.

   Account glyph ("gildong"): `.icon-my` (base/icons.css,
   ic-my-16-dark.svg) -- own native Portal asset now, not borrowed from
   admin. Logout: `.icon-logout` (ic-logout-16-dark.svg) -- also now
   provided. Both are mask-based, so they tint to white via
   `currentColor` on this dark bar same as every other icon, no separate
   white-variant export was needed despite the source files being
   "_dark" named. */

.top {
  box-sizing: border-box;
  /* Fixed, not a normal in-flow block -- it used to just scroll away with
     the rest of the page (a real reported bug: the design's own dark
     masthead is meant to stay put). Also load-bearing for the Tablet/
     Mobile drawer: .sidebar and its own ::backdrop (navigation.css)
     already position:fixed themselves at `top: 60px`, an assumption that only
     holds if the Top bar is genuinely anchored there regardless of
     scroll position -- without this, scrolling before opening the drawer
     left a stale 60px gap where the (no-longer-there) Top bar used to be. */
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 40;
  /* env(safe-area-inset-top) -- with viewport-fit=cover (base.html) now
     site-wide, .top's own fixed box would otherwise stop at the safe-area
     boundary same as before, leaving the OS's own default fill visible
     as a separate-colored strip above it instead of one continuous dark
     bar reaching the true top of the screen (reported live, most visible
     with a modal's own dim backdrop open, which highlighted the seam).
     `height` grows by the inset amount and `padding-top` claims exactly
     that much of it (box-sizing:border-box, set above) -- what's left for
     the actual content is still exactly the original 60px, so
     align-items:center below still centers the logo/buttons within that
     unchanged band rather than the taller box as a whole. */
  height: calc(60px + env(safe-area-inset-top));
  /* Left/right floors, not flat 16px/24px -- landscape on a notched
     phone (852-932px wide, squarely inside the <=1199px tier below, but
     this base rule is what's active above it) otherwise let the
     hamburger/logo render flush against the true left edge, right under
     a Dynamic Island/notch. Same max(Npx, env(safe-area-inset-*))
     pattern already applied to home.css's own sections; real report was
     the authenticated pages specifically (this bar renders on every one
     of them), not this bar's own home-page instance (which never shows
     here -- .top is authenticated-shell-only, see navigation.css's file
     note). */
  padding: 0 max(16px, env(safe-area-inset-right)) 0 max(24px, env(safe-area-inset-left));
  padding-top: env(safe-area-inset-top);
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  height: 60px;
  background: var(--color-top-bg);
}

.top-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.top-hamburger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--color-text-inverse);
  cursor: pointer;
}

.top-hamburger:active {
  background: var(--color-top-hover);
}

@media (hover: hover) {
  .top-hamburger:hover {
    background: var(--color-top-hover);
  }
}

/* The authenticated wordmark remains a home link but is not a button:
   no interaction fill may alter the shared top-bar brand artwork. */
.top-logo-link {
  display: flex;
  align-items: center;
}

.top-logo {
  display: block;
  width: 127px;
  height: 30px;
}

.top-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.top-account-group {
  display: flex;
  align-items: center;
  gap: 8px;
}

.topbar-button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0 10px;
  height: 32px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: none;
  text-decoration: none;
  font-family: var(--font-family);
  font-size: 14px;
  font-weight: 400;
  letter-spacing: var(--letter-spacing-tight);
  color: var(--color-text-inverse);
  cursor: pointer;
}

.topbar-button:active:not(:disabled) {
  background: var(--color-top-hover);
}

@media (hover: hover) {
  .topbar-button:hover:not(:disabled) {
    background: var(--color-top-hover);
  }
}

.topbar-button:disabled {
  color: rgba(255, 255, 255, 0.5);
  cursor: not-allowed;
}

/* 로그아웃 -- the one right-side button with a visible outline at rest,
   confirmed against the PNG (교육신청/gildong have none until hovered). */
.topbar-button-bordered {
  border-color: var(--color-top-divider);
}

.topbar-divider {
  width: 1px;
  height: 20px;
  background: var(--color-top-divider);
}

@media (max-width: 1199px) {
  .top-hamburger {
    display: flex;
  }

  .top {
    /* Same fix as the base rule above, at this tier's own 8px/16px
       floors -- this media query's equal specificity would otherwise
       silently win back to flat px at exactly the widths (<=1199px)
       every real landscape phone actually falls into. */
    padding: 0 max(16px, env(safe-area-inset-right)) 0 max(8px, env(safe-area-inset-left));
  }
}

@media (max-width: 767px) {
  /* Only gildong/로그아웃 drop from the bar here -- matches the Mobile
     PNG exactly (교육신청 stays, see file-level note above). They move to
     the drawer's .sidebar-footer instead (navigation.css). */
  .top-account-group {
    display: none;
  }
}

/* Pathologically narrow desktop-browser-resize case, not a real device
   width and not covered by any design export -- below ~250px even 교육신청
   alone (hamburger + shrunk logo + its own text) doesn't reliably fit on
   one line and wraps to several stacked vertical lines, blowing out
   .top's fixed 60px height (confirmed from a real narrow-desktop-resize
   screenshot). Only at this extreme does 교육신청 also drop from the bar,
   relocating to the drawer nav (.nav-training-mobile-only, same
   <=249px threshold, see navigation.css) -- per explicit user
   clarification that this was never meant to apply at real Mobile
   widths, see DEV_LOG 2026-07-21. */
@media (max-width: 249px) {
  .top-training-button {
    display: none;
  }
}

/* ---- Content region -- design-handoffs/asportal-public/design-guide/
   Portal_Resolution.css, confirmed against its own .png. ---- */

/* min-width: 0 -- unlike admin's own .main (which deliberately omits this,
   see admin's top.css comment: it WANTS flex's default min-width:auto so
   the whole app-shell overflows into a horizontal scrollbar below 1240px
   instead of reflowing, since admin has no mobile support at all). Portal
   needs the opposite: a real 3-tier responsive system (Portal_Resolution.css)
   where only the *table* should ever scroll horizontally, never the whole
   page. Without this, .main (a row-direction flex item of .app-shell)
   refuses to shrink below its own content's natural width -- confirmed via
   a real mobile-viewport bug report: at 390px the whole page silently
   grew to 724px wide (driven by the table's intrinsic width) and every
   mobile-only reflow rule below (search-fields restacking, table-scroll's
   own overflow-x) never actually triggered, because from inside that
   724px-wide .main there was "enough room" to fit everything on one line
   without wrapping. Table overflow now correctly stays isolated to
   .table-scroll's own horizontal scrollbar instead of blowing out .main/
   .content/.content-inner and the whole page with it. */
.main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.content {
  flex: 1;
}

/* PC (>=1200px): 24px side padding, content caps at 1240px and centers
   once the viewport is wider than nav (220px) + 1240px + padding --
   same numbers as admin's own content-inner, confirmed matching in the
   guide. Below 1200px the persistent .sidebar is gone entirely (replaced
   by the Tablet/Mobile drawer, see navigation.css) so there's no nav
   width to reserve room for any more -- content-inner just fills
   whatever's left of the viewport at 16px padding, no separate max-width
   of its own (the guide's "최대 1200px"/"최대 767px" labels under the
   Tablet/Mobile diagrams restate each tier's own breakpoint ceiling, not
   an independent content cap smaller than the viewport -- there's no
   Navigation column drawn in those two diagrams to reserve room for). */
.content-inner {
  max-width: 1240px;
  margin: 0 auto;
  padding: 24px;
  /* Left/right floors, not the flat 24px above -- centering plus the
     1240px cap means this padding is genuinely at the true viewport
     edge once the viewport's narrower than nav(220px)+1240px+padding,
     which real landscape phone widths always are. Same fix as .top
     above; breadcrumb/H1 were the exact elements reported rendering
     under a Dynamic Island in landscape. */
  padding-right: max(24px, env(safe-area-inset-right));
  padding-left: max(24px, env(safe-area-inset-left));
  box-sizing: border-box;
}

@media (max-width: 1199px) {
  .content-inner {
    max-width: none;
    padding: 16px;
    /* Same fix as the base rule above, at this tier's own 16px floor --
       this is the tier every real landscape phone actually falls into,
       so this override (not the base rule) is what was rendering the
       breadcrumb/H1 flush under the Dynamic Island. */
    padding-right: max(16px, env(safe-area-inset-right));
    padding-left: max(16px, env(safe-area-inset-left));
  }
}

/* Breadcrumb (page content, not part of the dark Top masthead -- Portal
   has no separate light title/breadcrumb strip the way admin's own
   .topbar does, confirmed against real screen PNGs like 패키지 현황/내
   정보: "Home › 화면명" sits directly above the page's own H1, inside
   .content-inner). No dedicated Portal_Breadcrumb guide export exists;
   ported admin's exact values (font-size/color/"›" separator) as a
   reasonable default until/unless a real export says otherwise. */
.breadcrumb {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
  overflow: hidden;
  white-space: nowrap;
}

.breadcrumb li {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: none;
  font-family: var(--font-family);
  font-size: 14px;
  font-weight: 400;
  letter-spacing: var(--letter-spacing-tight);
  color: var(--color-text-faint);
}

/* Every existing breadcrumb before SDK 다운로드's own "전체 버전" page was
   plain text, no middle crumb ever linked anywhere -- this is the first
   one with a real <a> (Home > SDK 다운로드 > {engine}, SDK 다운로드 links
   back to the main listing), which exposed the browser's own default
   link blue/visited-purple bleeding through since .breadcrumb li never
   had to override an anchor's color before. */
.breadcrumb li a {
  color: inherit;
  text-decoration: none;
}

@media (hover: hover) {
  .breadcrumb li a:hover {
    text-decoration: underline;
  }
}

.breadcrumb li:not(:first-child)::before {
  content: "›";
  margin-right: 4px;
}
