/* ==========================================================================
   Liquid Glass Design System — Butterfly component mapping
   --------------------------------------------------------------------------
   Butterfly keeps its markup and its behaviour; this file only re-dresses it.
   Rules here pick radii, spacing and layout — never blur, tint or shine,
   which belong to glass.css.

   `#id.glass` selectors are deliberate: Butterfly styles its shells with id
   selectors, so a plain `.glass` would lose the specificity fight.
   ========================================================================== */

/* ==========================================================================
   Frame
   ========================================================================== */

#body-wrap {
  overflow: visible;
  padding-top: calc(var(--g-nav-h) + 32px);
}

.layout {
  max-width: var(--g-max) !important;
  gap: var(--g-gap);
  padding: 0 24px;
}

.layout > .aside-content {
  max-width: 300px !important;
}

/* Kill the hero. `disable_top_img` removes the image, not the empty band. */
#page-header {
  background: transparent !important;
  height: auto !important;
  min-height: 0 !important;
}

#page-header:not(.not-top-img)::before {
  background-color: transparent !important;
}

#page-header #site-info,
#page-header #scroll-down {
  display: none !important;
}

/* ==========================================================================
   Navigation — floating soft glass bar
   ========================================================================== */

/* `disable_top_img` puts .not-top-img on the header, and Butterfly's rule for
   that state paints #nav a flat rgba(255,255,255,.8) — two ids beat our one,
   so the bar came out milky white no matter what the tint said. Restate the
   tint at matching specificity instead of bumping everything to !important. */
#page-header.not-top-img #nav.glass,
#page-header #nav.glass,
#nav.glass {
  background: var(--g-tint);
  box-shadow: var(--g-shine), var(--g-shadow);
}

#nav.glass {
  /* Square at the top, rounded at the bottom: the bar hangs off the viewport
     edge instead of floating below it. */
  --g-radius: 0 0 var(--g-r-xl) var(--g-r-xl);
  border-top: 0;
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
  right: 0 !important;
  margin-inline: auto;
  transform: none !important;
  z-index: 91;
  display: flex !important;
  align-items: center !important;
  width: min(calc(100% - 40px), var(--g-max)) !important;
  height: var(--g-nav-h);
  padding: 0 22px !important;
  box-sizing: border-box;
  opacity: 1 !important;
  transition:
    top var(--g-dur) var(--g-spring),
    height var(--g-dur) var(--g-spring),
    background-color var(--g-dur) var(--g-ease);
}

/* Butterfly toggles these on scroll; we only want the size change. */
#page-header.nav-fixed #nav.glass {
  top: 0 !important;
  height: 52px;
}

#nav #blog-info {
  flex: 1;
  min-width: 0;
}

#nav .site-name {
  font-weight: 700;
  letter-spacing: 0.4px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#nav,
#nav a,
#nav #blog-info,
#nav span.site-page,
#nav #toggle-menu,
#page-header.nav-fixed #nav,
#page-header.nav-fixed #nav a,
#page-header.nav-fixed #nav span.site-page {
  color: var(--g-ink);
  text-shadow: none !important;
}

/* Butterfly lays the nav out with inline boxes at three different font sizes:
   menu items and the search button at .78em, the collapsed hamburger at the
   nav's own size. Inline boxes of different sizes sit on a shared baseline,
   not a shared centre line, so the buttons came out at visibly different
   heights. One flex row, one font size, everything centred. */
#page-header #nav #menus {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}

/* Butterfly collapses the menu into the hamburger by putting .hide-menu on
   #nav, and its own rule for that (`#nav.hide-menu .menus_items`) is one id
   short of ours — so the row stayed visible on phones and squeezed the title
   out of the bar. Exclude the collapsed state here rather than fight it. */
#page-header #nav:not(.hide-menu) .menus_items {
  display: flex;
  align-items: center;
}

#page-header #nav.hide-menu .menus_items {
  display: none;
}

#page-header #nav #search-button,
#page-header #nav .menus_item {
  display: inline-flex;
  align-items: center;
  padding: 0 0 0 14px;
}

/* The hamburger only ever shows in the collapsed layout (responsive.css sets
   its display there); here it just gets the same box as the other buttons.
   Butterfly pins it to inline-block with !important, so unlike the search
   button it keeps a text strut — making its span block-level drops the strut
   and the two icon buttons land on exactly the same centre line. */
#page-header #nav #toggle-menu {
  align-items: center;
  padding: 0 0 0 14px;
}

/* Two ids to beat Butterfly's `#page-header #nav .site-page` (otherwise its
   padding-bottom survives our shorthand and the box sits lopsided), and three
   on the hamburger to beat `#nav.hide-menu #toggle-menu .site-page`, which
   resets it to the nav's full font size — the mismatched-height culprit. */
#page-header #nav .site-page,
#page-header #nav #toggle-menu .site-page,
#nav .site-page {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  border-radius: var(--g-r-sm);
  padding: 0.32em 0.75em;
  font-size: 0.86em;
  line-height: 1.5;
  transition:
    background-color var(--g-dur-fast) var(--g-ease),
    transform var(--g-dur-fast) var(--g-spring);
}

#page-header #nav #toggle-menu .site-page {
  display: flex;
}

#page-header #nav .site-page:hover,
#nav .site-page:hover {
  transform: translateY(-1px);
}

/* One hover indicator, and it is the underline. Butterfly's own bar is kept
   but restated in the warm accent and pinned to a shared baseline — items and
   the search button have different box heights, so `bottom: 0` alone put the
   bars at two different heights. */
#page-header #nav .site-page:not(.child)::after {
  bottom: 2px;
  left: 0.75em;
  z-index: 0;
  width: 0;
  height: 3px;
  border-radius: var(--g-r-pill);
  background-color: var(--g-accent);
  transition: width var(--g-dur-fast) var(--g-ease);
}

#page-header #nav .site-page:not(.child):hover::after {
  width: calc(100% - 1.5em);
}

#nav .menus_item_child {
  border-radius: var(--g-r-md);
  overflow: hidden;
  background: var(--g-bg);
  box-shadow: var(--g-shadow-lift);
}

/* --------------------------------------------------------------------------
   Scroll edge effect (§46)
   --------------------------------------------------------------------------
   Not "navbar opacity up". As content arrives under the bar, the bar separates
   from the page: its tint firms, its rim brightens and a dissolve appears
   along its lower edge so text passing beneath fades instead of colliding.
   glass-motion.js toggles .glass-scrolled on <html> after the first ~3px and
   writes a continuous 0..1 value to --g-scroll-edge on :root.
   -------------------------------------------------------------------------- */

html.glass-scrolled #nav.glass {
  --g-tint: rgba(255, 250, 243, 0.52);
  --g-edge: rgba(255, 255, 255, 0.68);
  box-shadow:
    var(--g-shine),
    var(--g-shadow),
    inset 0 -20px 28px -20px rgba(255, 255, 255, 0.58);
}

html.glass-scrolled #nav.glass::before {
  background:
    linear-gradient(
      158deg,
      rgba(255, 255, 255, 0.50) 0%,
      rgba(255, 255, 255, 0.12) 10%,
      rgba(255, 255, 255, 0.00) 26%,
      rgba(255, 255, 255, 0.00) 82%,
      rgba(255, 226, 186, 0.20) 100%
    );
}

html[data-theme="dark"].glass-scrolled #nav.glass {
  --g-tint: rgba(56, 42, 32, 0.62);
  --g-edge: rgba(255, 232, 205, 0.34);
  box-shadow:
    var(--g-shine),
    var(--g-shadow),
    inset 0 -20px 28px -20px rgba(0, 0, 0, 0.55);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]).glass-scrolled #nav.glass {
    --g-tint: rgba(56, 42, 32, 0.62);
    --g-edge: rgba(255, 232, 205, 0.34);
    box-shadow:
      var(--g-shine),
      var(--g-shadow),
      inset 0 -20px 28px -20px rgba(0, 0, 0, 0.55);
  }
}

/* ==========================================================================
   Home — post card grid
   ========================================================================== */

#recent-posts .recent-post-items {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--g-gap);
}

#recent-posts .recent-post-item.glass {
  display: flex !important;
  flex-direction: column !important;
  width: auto !important;
  height: 100% !important;
  margin: 0 !important;
  padding: 12px !important;
  overflow: hidden;
}

#recent-posts .recent-post-item .post_cover {
  width: 100% !important;
  height: auto !important;
  aspect-ratio: 3 / 2;
  flex: none !important;
  order: -1 !important;
  padding: 0 !important;
  margin: 0 !important;
  border-radius: calc(var(--g-radius) - 12px);
  overflow: hidden;
}

#recent-posts .recent-post-item .post_cover a,
#recent-posts .recent-post-item .post_cover img {
  border-radius: inherit;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

#recent-posts .recent-post-item .post-bg {
  transition: transform 0.9s var(--g-ease);
}

#recent-posts .recent-post-item:hover .post-bg {
  transform: scale(1.06);
}

#recent-posts .recent-post-item .recent-post-info {
  width: auto !important;
  padding: 18px 16px 14px !important;
  display: flex;
  flex-direction: column;
  gap: 9px;
  flex: 1 1 auto;
}

#recent-posts .recent-post-item .article-title {
  font-size: 1.4rem;
  line-height: 1.4;
  font-weight: 700;
  color: var(--g-ink);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

#recent-posts .recent-post-item .content {
  font-size: 0.95rem;
  line-height: 1.75;
  color: var(--g-ink-dim);
  display: -webkit-box;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

#recent-posts .recent-post-item .article-meta-wrap {
  font-size: 0.78rem;
  color: var(--g-ink-mute);
  margin-top: auto;
}

#recent-posts .recent-post-item .article-meta-wrap a {
  color: var(--g-accent);
}

/* ==========================================================================
   Aside
   ========================================================================== */

#aside-content .card-widget.glass {
  border: 1px solid var(--g-edge);
  box-shadow: var(--g-shine), var(--g-shadow);
  padding: 20px !important;
  margin-bottom: var(--g-gap);
}

#aside-content .item-headline {
  font-weight: 700;
  letter-spacing: 0.3px;
  color: var(--g-ink);
}

#aside-content .card-info {
  text-align: center;
}

/* The portrait is left as Butterfly draws it -- upstream already clips it to
   a circle. It briefly carried a glass dome of its own; a refracting lens
   sitting on a face fights the face, and it has been removed. The margin is
   kept because the card's spacing was tuned around it. */
#aside-content .card-info .avatar-img {
  margin: 6px auto 16px;
}

#aside-content .card-info .author-info-name {
  font-weight: 700;
  font-size: 1.3rem;
  color: var(--g-ink);
  margin: 10px 0 4px;
}

#aside-content .card-info .author-info-description {
  font-size: 0.86rem;
  color: var(--g-ink-dim);
  margin-bottom: 14px;
}

#aside-content .card-info .card-info-social-icons a {
  color: var(--g-ink-dim);
}

#aside-content .card-info #card-info-btn {
  background: var(--g-accent);
  border-radius: var(--g-r-pill);
  color: #fff;
  transition: transform var(--g-dur-fast) var(--g-spring);
}

#aside-content .card-info #card-info-btn:hover {
  transform: translateY(-2px);
}

#aside-content .card-tag-cloud a,
#aside-content .card-categories .card-category-list-link {
  color: var(--g-ink-dim);
  transition: color var(--g-dur-fast) var(--g-ease);
}

#aside-content .card-tag-cloud a:hover,
#aside-content .card-categories .card-category-list-link:hover {
  color: var(--g-accent);
}

/* TOC */

#card-toc.glass .toc-content .toc-link.active,
#card-toc .toc-content .toc-link:hover {
  color: var(--g-accent);
}

#card-toc .toc-content .toc-link.active {
  background: color-mix(in srgb, var(--g-accent) 16%, transparent);
  border-radius: 6px;
}

/* ==========================================================================
   Right rail, pagination, footer
   ========================================================================== */

#rightside button.glass,
#rightside > div > button {
  --g-radius: var(--g-r-md);
  border-radius: var(--g-r-md) !important;
  color: var(--g-ink);
  transition: transform var(--g-dur-fast) var(--g-spring),
              background-color var(--g-dur-fast) var(--g-ease);
}

#rightside button.glass:hover {
  transform: scale(1.08);
}

#pagination .page-number.glass,
#pagination .extend.glass {
  --g-radius: var(--g-r-sm);
  border-radius: var(--g-r-sm);
  color: var(--g-ink);
}

#pagination .page-number.current {
  background: var(--g-accent) !important;
  color: #fff !important;
  border-color: transparent;
}

#footer {
  background: transparent !important;
}

#footer::before {
  display: none;
}

#footer-wrap {
  padding: 30px 0;
  color: var(--g-ink-dim);
}

#footer-wrap a {
  color: var(--g-accent);
}

/* ==========================================================================
   Tags / categories / archives
   ========================================================================== */

/* Hexo's tag_cloud helper writes a random background colour inline, which is
   the one thing in the theme that cannot be reached without !important. The
   inline font-size stays — it is what encodes how often a tag is used. */
.tag-cloud-list a.glass,
#article-container .tag-list a.glass {
  --g-radius: var(--g-r-pill);
  display: inline-block;
  padding: 0.3em 0.95em;
  margin: 0.3em 0.22em;
  background-color: var(--g-tint) !important;
  color: var(--g-ink) !important;
}

.tag-cloud-list a.glass:hover,
#article-container .tag-list a.glass:hover {
  background-color: var(--g-tint-hover) !important;
  color: var(--g-accent) !important;
}

#page .tag-cloud-list,
#tag .tag-cloud-list {
  padding: 0.6em 0;
}

/* Butterfly's archive timeline is hard-coded to its blue ramp (the rail is a
   border, the nodes are borders too), so each part is restated in warm. */
.article-sort {
  border-left-color: color-mix(in srgb, var(--g-accent) 45%, transparent);
}

.article-sort-title::before,
.article-sort-item::before,
.article-sort-item.year::before {
  border-color: var(--g-accent);
}

.article-sort-title::after {
  background: color-mix(in srgb, var(--g-accent) 45%, transparent);
}

.article-sort-title:hover::before,
.article-sort-item:hover::before {
  border-color: var(--g-terracotta);
}

/* Butterfly draws the timeline node on the row's ::before — the same pseudo
   the glass material uses for its top-light. On a glass row the two collide:
   `inset: 0` pulls the node off the rail and onto the panel's own left edge,
   and the highlight shrinks to the node's 6px box. So ::before goes back to
   being glass, and the node is redrawn on the row's free ::after. */
#archive .article-sort-item.glass::before {
  inset: 0;
  width: auto;
  height: auto;
  border: 0;
  border-radius: inherit;
  background: var(--g-highlight);
  transform: none;
}

#archive .article-sort-item.glass::after {
  content: "";
  position: absolute;
  /* 20px of rail padding + 17px back over the row's own offset, the same
     geometry Butterfly uses, so glass rows and year markers share a rail. */
  left: calc(-20px - 17px);
  top: 50%;
  width: 6px;
  height: 6px;
  border: 3px solid var(--g-accent);
  border-radius: 6px;
  background: var(--g-bg);
  transform: translateY(-50%);
  transition: border-color var(--g-dur-fast) var(--g-ease);
}

#archive .article-sort-item.glass:hover::after {
  border-color: var(--g-terracotta);
}

.article-sort-item-title,
.article-sort-title {
  color: var(--g-ink);
}

.article-sort-item-title:hover {
  color: var(--g-accent);
}

.article-sort-item-img {
  border-radius: var(--g-r-sm);
}

/* Each timeline row is a glass panel, and Butterfly gives the row no padding
   of its own — so the date and title sat straight on the rim. At the soft
   weight's pill radius the rounded ends then cut across the text entirely.
   Card radius plus a real inset puts the content back inside the panel. */
#archive .article-sort-item.glass {
  --g-radius: var(--g-r-md);
  box-sizing: border-box;
  padding: 14px 22px;
  gap: 4px;
}

/* The cover-less row is pinned to 80px upstream; with padding added that
   squeezes the two lines, so it becomes a floor instead of a fixed height. */
#archive .article-sort-item.no-article-cover.glass {
  height: auto;
  min-height: 78px;
}

/* The node dot is positioned against the row box, which has not moved — but
   the covered row's own inner padding now doubles up with ours. */
#archive .article-sort-item.glass .article-sort-item-info {
  padding: 0 0 0 16px;
}

#archive .article-sort-item.no-article-cover.glass .article-sort-item-info {
  padding: 0;
}

/* ==========================================================================
   Overlays — search, mobile drawer
   ========================================================================== */

/* `.glass` and `.search-dialog` have the same specificity, and the material
   loads last — so its `position: relative` quietly beat the theme's
   `position: fixed` and the dialog rendered in flow at the very bottom of the
   document instead of over it. Every other geometry declaration the theme
   makes (top, left, margin, size, and its own 768px full-screen block) is
   still in force; only the positioning scheme has to be handed back. */
#local-search .search-dialog.glass,
.search-dialog.glass {
  position: fixed;
  border: 1px solid var(--g-edge);
  overflow: hidden;
}

#search-mask {
  background: rgba(24, 14, 8, 0.42);
}

.search-dialog .search-nav {
  color: var(--g-ink);
}

#local-search-input input,
.search-dialog input {
  background: color-mix(in srgb, var(--g-ink) 8%, transparent);
  border: 1px solid var(--g-edge);
  border-radius: var(--g-r-pill);
  color: var(--g-ink);
  padding: 0.5em 1em;
}

/* Two ids on the theme's side (`#sidebar #sidebar-menus`) against one on
   ours, so the drawer kept its flat --sidebar-bg fill and was the one surface
   in the blog that was not glass. Restate the material at matching
   specificity; the geometry below stays where it was. */
#sidebar #sidebar-menus.glass,
#sidebar-menus.glass {
  /* Firmer than the floating weight it inherits. Every other overlay in the
     blog covers a few hundred pixels of page; the drawer covers the full
     height of it, so the menu has to stay readable against whatever happens
     to be behind it — a paragraph, a code block, a cover image. */
  --g-tint: rgba(255, 250, 243, 0.62);
  --g-radius: var(--g-r-xl) 0 0 var(--g-r-xl);
  border-radius: var(--g-r-xl) 0 0 var(--g-r-xl);
  background: var(--g-tint);
  background-image: none;
  border: 1px solid var(--g-edge);
  border-right: none;
  box-shadow: var(--g-shine), var(--g-shadow-lift);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) #sidebar #sidebar-menus.glass {
    --g-tint: rgba(34, 24, 18, 0.62);
  }
}

[data-theme="dark"] #sidebar #sidebar-menus.glass {
  --g-tint: rgba(34, 24, 18, 0.62);
}

/* The menu block inside the drawer is a second opaque panel in the theme.
   It stays a panel — a wash on top of the drawer's own, so it reads as glass
   resting on glass rather than a second sheet of it. */
#sidebar #sidebar-menus .menus_items {
  background: rgba(255, 255, 255, 0.34);
  border: 1px solid var(--g-edge);
  border-radius: var(--g-r-md);
  box-shadow: var(--g-shine);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) #sidebar #sidebar-menus .menus_items {
    background: rgba(255, 246, 235, 0.10);
  }
}

[data-theme="dark"] #sidebar #sidebar-menus .menus_items {
  background: rgba(255, 246, 235, 0.10);
}

#sidebar-menus .sidebar-menu-item a,
#sidebar-menus .site-data a,
#sidebar-menus .menus_items .site-page {
  color: var(--g-ink);
}

#sidebar-menus .menus_items .site-page:hover {
  background: var(--g-tint-hover);
  color: var(--g-accent);
  box-shadow: none;
}

/* The scrim behind the drawer is 80% black upstream, which leaves the glass
   nothing to refract. Lighten it until the page still reads through. */
#sidebar #menu-mask {
  background: rgba(24, 14, 8, 0.55);
}

/* Butterfly spins the avatar a full turn on hover, and the social icons with
   it. The glass system's hover language is lift and tint, not rotation. */
.avatar-img img:hover,
#aside-content .card-info-social-icons i:hover {
  transform: none;
}

/* ==========================================================================
   Selection & scrollbar
   ========================================================================== */

::selection {
  background: color-mix(in srgb, var(--g-accent) 34%, transparent);
  color: var(--g-ink);
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--g-accent) 45%, transparent);
  border-radius: var(--g-r-pill);
}

::-webkit-scrollbar-thumb:hover {
  background: var(--g-accent);
}

::-webkit-scrollbar-track {
  background: transparent;
}

/* ==========================================================================
   Entrance
   --------------------------------------------------------------------------
   Cards rise into place once on load. Staggered by nth-child rather than by
   script so it survives PJAX without any bookkeeping.
   ========================================================================== */

@keyframes g-rise {
  from { opacity: 0; transform: translateY(18px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}

#recent-posts .recent-post-item.glass,
#aside-content .card-widget.glass,
#post.glass,
#page.glass,
#archive.glass,
#tag.glass,
#category.glass {
  /* `backwards` holds the hidden state through the stagger delay but releases
     after the entrance instead of pinning transform forever. */
  animation: g-rise 0.62s var(--g-ease) backwards;
}

#recent-posts .recent-post-item:nth-child(2) { animation-delay: 0.06s; }
#recent-posts .recent-post-item:nth-child(3) { animation-delay: 0.12s; }
#recent-posts .recent-post-item:nth-child(4) { animation-delay: 0.18s; }
#recent-posts .recent-post-item:nth-child(5) { animation-delay: 0.24s; }
#recent-posts .recent-post-item:nth-child(n+6) { animation-delay: 0.3s; }

#aside-content .card-widget:nth-child(2) { animation-delay: 0.08s; }
#aside-content .card-widget:nth-child(3) { animation-delay: 0.14s; }
#aside-content .card-widget:nth-child(n+4) { animation-delay: 0.2s; }
