/* ============================================================
   Market Meridian — auth pages (login, MFA, forgot, reset)

   Default theme: dark.
   - User explicit choice via <html data-theme="dark|light">.
   - Auto follow OS via @media (prefers-color-scheme: light),
     but ONLY when no explicit choice has been made
     (:root:not([data-theme])).
   ============================================================ */

:root {
  /* Inline SVGs as base64 data URIs so the logo + bg-waves arrive
     with the CSS file (single render-blocking request) instead of
     triggering separate image fetches that pop in late on refresh. */
  --mm-logo-url:  url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgICAgdmlld0JveD0iLTQwIC00MCAxMTYyIDEwNjQiCiAgICAgd2lkdGg9IjEwODIiIGhlaWdodD0iOTg0IgogICAgIHJvbGU9ImltZyIgYXJpYS1sYWJlbD0iTWFya2V0IE1lcmlkaWFuIGxvZ28iPgogIDx0aXRsZT5NYXJrZXQgTWVyaWRpYW48L3RpdGxlPgoKICA8ZGVmcz4KICAgIDwhLS0gV2FybSBwZXd0ZXIvc3RvbmUgZ3JhZGllbnQgZm9yIHRoZSBNIGJvZHkuIC0tPgogICAgPGxpbmVhckdyYWRpZW50IGlkPSJzaWx2ZXJGYWNlIiB4MT0iMC4xNSIgeTE9IjAiIHgyPSIwLjg1IiB5Mj0iMSI+CiAgICAgIDxzdG9wIG9mZnNldD0iMCUiICAgc3RvcC1jb2xvcj0iI2M4YmZiNyIvPgogICAgICA8c3RvcCBvZmZzZXQ9IjI1JSIgIHN0b3AtY29sb3I9IiNhNTljOTUiLz4KICAgICAgPHN0b3Agb2Zmc2V0PSI1NSUiICBzdG9wLWNvbG9yPSIjNzk2ZjY3Ii8+CiAgICAgIDxzdG9wIG9mZnNldD0iODAlIiAgc3RvcC1jb2xvcj0iIzg1N2I3MyIvPgogICAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM0YTQyMzkiLz4KICAgIDwvbGluZWFyR3JhZGllbnQ+CgogICAgPCEtLSBHb2xkIGdyYWRpZW50IGZvciB0aGUgY2hhcnQtbGluZSBhY2NlbnQuIC0tPgogICAgPGxpbmVhckdyYWRpZW50IGlkPSJnb2xkRmFjZSIgeDE9IjAiIHkxPSIwLjIiIHgyPSIxIiB5Mj0iMC45Ij4KICAgICAgPHN0b3Agb2Zmc2V0PSIwJSIgICBzdG9wLWNvbG9yPSIjZjBjZDk0Ii8+CiAgICAgIDxzdG9wIG9mZnNldD0iMzUlIiAgc3RvcC1jb2xvcj0iI2Q0YWI2ZSIvPgogICAgICA8c3RvcCBvZmZzZXQ9IjY1JSIgIHN0b3AtY29sb3I9IiNhYjgzNGQiLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjNmI0ZDI4Ii8+CiAgICA8L2xpbmVhckdyYWRpZW50PgoKICAgIDwhLS0gQnJ1c2hlZCBjYXN0LW1ldGFsIHRleHR1cmUuIFR3byBub2lzZSBsYXllcnMgKGxhcmdlIGlzb3Ryb3BpYwogICAgICAgICBkaXZvdHMgKyBmaW5lIGhvcml6b250YWwgYnJ1c2ggc3RyaWF0aW9ucykgbWFwcGVkIHRvIGx1bWluYW5jZQogICAgICAgICBhbmQgbXVsdGlwbGllZCBvbnRvIHRoZSBncmFkaWVudC4gLS0+CiAgICA8ZmlsdGVyIGlkPSJzdG9uZVRleCIgeD0iLTUlIiB5PSItNSUiIHdpZHRoPSIxMTAlIiBoZWlnaHQ9IjExMCUiPgogICAgICA8IS0tIExheWVyIEE6IGxhcmdlIGlzb3Ryb3BpYyBkaXZvdHMgLS0+CiAgICAgIDxmZVR1cmJ1bGVuY2UgdHlwZT0iZnJhY3RhbE5vaXNlIiBiYXNlRnJlcXVlbmN5PSIwLjQ1IiBudW1PY3RhdmVzPSIzIiBzZWVkPSIxMyIgcmVzdWx0PSJyYXdBIi8+CiAgICAgIDxmZUNvbXBvbmVudFRyYW5zZmVyIGluPSJyYXdBIiByZXN1bHQ9Imx1bUEiPgogICAgICAgIDxmZUZ1bmNSIHR5cGU9ImxpbmVhciIgc2xvcGU9IjAuODIiIGludGVyY2VwdD0iMC4xOCIvPgogICAgICAgIDxmZUZ1bmNHIHR5cGU9ImxpbmVhciIgc2xvcGU9IjAuODIiIGludGVyY2VwdD0iMC4xOCIvPgogICAgICAgIDxmZUZ1bmNCIHR5cGU9ImxpbmVhciIgc2xvcGU9IjAuODIiIGludGVyY2VwdD0iMC4xOCIvPgogICAgICAgIDxmZUZ1bmNBIHR5cGU9ImRpc2NyZXRlIiB0YWJsZVZhbHVlcz0iMSIvPgogICAgICA8L2ZlQ29tcG9uZW50VHJhbnNmZXI+CgogICAgICA8IS0tIExheWVyIEI6IGFuaXNvdHJvcGljIGhvcml6b250YWwgYnJ1c2ggc3RyaWF0aW9ucyAtLT4KICAgICAgPGZlVHVyYnVsZW5jZSB0eXBlPSJmcmFjdGFsTm9pc2UiIGJhc2VGcmVxdWVuY3k9IjMuNSAwLjA2IiBudW1PY3RhdmVzPSIyIiBzZWVkPSI3IiByZXN1bHQ9InJhd0IiLz4KICAgICAgPGZlQ29tcG9uZW50VHJhbnNmZXIgaW49InJhd0IiIHJlc3VsdD0ibHVtQiI+CiAgICAgICAgPGZlRnVuY1IgdHlwZT0ibGluZWFyIiBzbG9wZT0iMC41OSIgaW50ZXJjZXB0PSIwLjQxIi8+CiAgICAgICAgPGZlRnVuY0cgdHlwZT0ibGluZWFyIiBzbG9wZT0iMC41OSIgaW50ZXJjZXB0PSIwLjQxIi8+CiAgICAgICAgPGZlRnVuY0IgdHlwZT0ibGluZWFyIiBzbG9wZT0iMC41OSIgaW50ZXJjZXB0PSIwLjQxIi8+CiAgICAgICAgPGZlRnVuY0EgdHlwZT0iZGlzY3JldGUiIHRhYmxlVmFsdWVzPSIxIi8+CiAgICAgIDwvZmVDb21wb25lbnRUcmFuc2Zlcj4KCiAgICAgIDwhLS0gQ29tYmluZSB0aGUgdHdvIGx1bWluYW5jZSBtYXBzIC0tPgogICAgICA8ZmVDb21wb3NpdGUgaW49Imx1bUEiIGluMj0ibHVtQiIgb3BlcmF0b3I9ImFyaXRobWV0aWMiCiAgICAgICAgICAgICAgICAgICBrMT0iMSIgazI9IjAiIGszPSIwIiBrND0iMCIgcmVzdWx0PSJsdW1Db21iaW5lZCIvPgoKICAgICAgPCEtLSBDbGlwIHRleHR1cmUgdG8gc2hhcGUsIHRoZW4gbXVsdGlwbHkgb250byB0aGUgZ3JhZGllbnQgLS0+CiAgICAgIDxmZUNvbXBvc2l0ZSBpbj0ibHVtQ29tYmluZWQiIGluMj0iU291cmNlR3JhcGhpYyIgb3BlcmF0b3I9ImluIiByZXN1bHQ9InRleHR1cmVDbGlwcGVkIi8+CiAgICAgIDxmZUNvbXBvc2l0ZSBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJ0ZXh0dXJlQ2xpcHBlZCIgb3BlcmF0b3I9ImFyaXRobWV0aWMiCiAgICAgICAgICAgICAgICAgICBrMT0iMSIgazI9IjAiIGszPSIwIiBrND0iMCIvPgogICAgPC9maWx0ZXI+CgogICAgPCEtLSBSYWlzZWQgZW1ib3NzOiBzdWJ0bGUgaGlnaGxpZ2h0IG9uIHRoZSB0b3AtbGVmdCBlZGdlLCBzbGlnaHRseQogICAgICAgICBzdHJvbmdlciBzaGFkb3cgb24gdGhlIGJvdHRvbS1yaWdodCwgcGx1cyBhIHNvZnQgZHJvcCBzaGFkb3cuIC0tPgogICAgPGZpbHRlciBpZD0iZW1ib3NzIiB4PSItMjUlIiB5PSItMjUlIiB3aWR0aD0iMTUwJSIgaGVpZ2h0PSIxNTAlIj4KICAgICAgPCEtLSBEcm9wIHNoYWRvdyB1bmRlciB0aGUgc2hhcGUgLS0+CiAgICAgIDxmZUdhdXNzaWFuQmx1ciBpbj0iU291cmNlQWxwaGEiIHN0ZERldmlhdGlvbj0iOSIgcmVzdWx0PSJkcy1ibHVyIi8+CiAgICAgIDxmZU9mZnNldCBpbj0iZHMtYmx1ciIgZHg9IjAiIGR5PSIxNiIgcmVzdWx0PSJkcy1vZmYiLz4KICAgICAgPGZlQ29tcG9uZW50VHJhbnNmZXIgaW49ImRzLW9mZiIgcmVzdWx0PSJkcyI+CiAgICAgICAgPGZlRnVuY0EgdHlwZT0ibGluZWFyIiBzbG9wZT0iMC43NSIvPgogICAgICA8L2ZlQ29tcG9uZW50VHJhbnNmZXI+CgogICAgICA8IS0tIExpZ2h0IGVkZ2UsIHRvcC1sZWZ0IC0tPgogICAgICA8ZmVNb3JwaG9sb2d5IGluPSJTb3VyY2VBbHBoYSIgb3BlcmF0b3I9ImVyb2RlIiByYWRpdXM9IjIiIHJlc3VsdD0ic2hydW5rIi8+CiAgICAgIDxmZU9mZnNldCBpbj0ic2hydW5rIiBkeD0iMiIgZHk9IjIiIHJlc3VsdD0ibGlnaHRPZmYiLz4KICAgICAgPGZlQ29tcG9zaXRlIGluPSJTb3VyY2VBbHBoYSIgaW4yPSJsaWdodE9mZiIgb3BlcmF0b3I9Im91dCIgcmVzdWx0PSJsaWdodEVkZ2UiLz4KICAgICAgPGZlR2F1c3NpYW5CbHVyIGluPSJsaWdodEVkZ2UiIHN0ZERldmlhdGlvbj0iMS4yIiByZXN1bHQ9ImxpZ2h0RWRnZVNvZnQiLz4KICAgICAgPGZlRmxvb2QgZmxvb2QtY29sb3I9IiNmZmZmZmYiIGZsb29kLW9wYWNpdHk9IjAuNDUiLz4KICAgICAgPGZlQ29tcG9zaXRlIGluMj0ibGlnaHRFZGdlU29mdCIgb3BlcmF0b3I9ImluIiByZXN1bHQ9ImxpZ2h0SW5uZXIiLz4KCiAgICAgIDwhLS0gRGFyayBlZGdlLCBib3R0b20tcmlnaHQgLS0+CiAgICAgIDxmZU9mZnNldCBpbj0ic2hydW5rIiBkeD0iLTMiIGR5PSItMyIgcmVzdWx0PSJkYXJrT2ZmIi8+CiAgICAgIDxmZUNvbXBvc2l0ZSBpbj0iU291cmNlQWxwaGEiIGluMj0iZGFya09mZiIgb3BlcmF0b3I9Im91dCIgcmVzdWx0PSJkYXJrRWRnZSIvPgogICAgICA8ZmVHYXVzc2lhbkJsdXIgaW49ImRhcmtFZGdlIiBzdGREZXZpYXRpb249IjEuMCIgcmVzdWx0PSJkYXJrRWRnZVNvZnQiLz4KICAgICAgPGZlRmxvb2QgZmxvb2QtY29sb3I9IiMwMDAwMDAiIGZsb29kLW9wYWNpdHk9IjAuNTUiLz4KICAgICAgPGZlQ29tcG9zaXRlIGluMj0iZGFya0VkZ2VTb2Z0IiBvcGVyYXRvcj0iaW4iIHJlc3VsdD0iZGFya0lubmVyIi8+CgogICAgICA8ZmVNZXJnZT4KICAgICAgICA8ZmVNZXJnZU5vZGUgaW49ImRzIi8+CiAgICAgICAgPGZlTWVyZ2VOb2RlIGluPSJTb3VyY2VHcmFwaGljIi8+CiAgICAgICAgPGZlTWVyZ2VOb2RlIGluPSJkYXJrSW5uZXIiLz4KICAgICAgICA8ZmVNZXJnZU5vZGUgaW49ImxpZ2h0SW5uZXIiLz4KICAgICAgPC9mZU1lcmdlPgogICAgPC9maWx0ZXI+CiAgPC9kZWZzPgoKICA8IS0tIFRoZSBNIHNoYXBlIGFuZCB0aGUgY2hhcnQtbGluZSwgYm90aCBydW4gdGhyb3VnaCB0aGUgZW1ib3NzIGZpbHRlcgogICAgICAgYW5kIGluZGl2aWR1YWxseSB0ZXh0dXJlZC4gLS0+CiAgPGcgZmlsdGVyPSJ1cmwoI2VtYm9zcykiPgogICAgPHBhdGggZD0iTSAxNCA5NjcgTCAxNzggNzkyIEwgMTc4IDI5NSBMIDQ5NiA1OTIgTCA2NDEgNDQ0IEwgNjk4IDQ5OCBMIDEwNjQgMTUwIEwgMTA2NCAxNyBMIDg2MSAxNTMgTCA1NDUgMzU4IEwgMTQgMTQgWiIKICAgICAgICAgIGZpbGw9InVybCgjc2lsdmVyRmFjZSkiCiAgICAgICAgICBmaWx0ZXI9InVybCgjc3RvbmVUZXgpIi8+CiAgICA8cGF0aCBkPSJNIDEwNjQgMjIwIEwgNjk1IDU3NSBMIDY0MSA1MjQgTCA0NjUgNjk5IEwgMzcxIDYwMiBMIDE5NSA4MDggTCA3NiA5NTQgTCAzNDEgNzQxIEwgNDc4IDg5NyBMIDkwNCA0NDggTCA5MDUgODAyIEwgMTA2NCA5NjAgWiIKICAgICAgICAgIGZpbGw9InVybCgjZ29sZEZhY2UpIgogICAgICAgICAgZmlsdGVyPSJ1cmwoI3N0b25lVGV4KSIvPgogIDwvZz4KPC9zdmc+Cg==');
  /* Simplified flat variant for the small topbar mark. The full
     SVG's brushed-metal texture + emboss filters need way more
     pixels than 32x32 to look right — they degrade into fuzzy
     noise at that size. This flat version is gradient-only. */
  --mm-logo-flat-url: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMTQgMTA3OCA5NTYiIHJvbGU9ImltZyIgYXJpYS1sYWJlbD0iTWFya2V0IE1lcmlkaWFuIj4KICA8ZGVmcz4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0icyIgeDE9IjAuMTUiIHkxPSIwIiB4Mj0iMC44NSIgeTI9IjEiPgogICAgICA8c3RvcCBvZmZzZXQ9IjAlIiAgIHN0b3AtY29sb3I9IiNjOGJmYjciLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIyNSUiICBzdG9wLWNvbG9yPSIjYTU5Yzk1Ii8+CiAgICAgIDxzdG9wIG9mZnNldD0iNTUlIiAgc3RvcC1jb2xvcj0iIzc5NmY2NyIvPgogICAgICA8c3RvcCBvZmZzZXQ9IjgwJSIgIHN0b3AtY29sb3I9IiM4NTdiNzMiLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjNGE0MjM5Ii8+CiAgICA8L2xpbmVhckdyYWRpZW50PgogICAgPGxpbmVhckdyYWRpZW50IGlkPSJnIiB4MT0iMCIgeTE9IjAuMiIgeDI9IjEiIHkyPSIwLjkiPgogICAgICA8c3RvcCBvZmZzZXQ9IjAlIiAgIHN0b3AtY29sb3I9IiNmMGNkOTQiLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIzNSUiICBzdG9wLWNvbG9yPSIjZDRhYjZlIi8+CiAgICAgIDxzdG9wIG9mZnNldD0iNjUlIiAgc3RvcC1jb2xvcj0iI2FiODM0ZCIvPgogICAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM2YjRkMjgiLz4KICAgIDwvbGluZWFyR3JhZGllbnQ+CiAgPC9kZWZzPgogIDxwYXRoIGQ9Ik0gMTQgOTY3IEwgMTc4IDc5MiBMIDE3OCAyOTUgTCA0OTYgNTkyIEwgNjQxIDQ0NCBMIDY5OCA0OTggTCAxMDY0IDE1MCBMIDEwNjQgMTcgTCA4NjEgMTUzIEwgNTQ1IDM1OCBMIDE0IDE0IFoiIGZpbGw9InVybCgjcykiLz4KICA8cGF0aCBkPSJNIDEwNjQgMjIwIEwgNjk1IDU3NSBMIDY0MSA1MjQgTCA0NjUgNjk5IEwgMzcxIDYwMiBMIDE5NSA4MDggTCA3NiA5NTQgTCAzNDEgNzQxIEwgNDc4IDg5NyBMIDkwNCA0NDggTCA5MDUgODAyIEwgMTA2NCA5NjAgWiIgZmlsbD0idXJsKCNnKSIvPgo8L3N2Zz4K');
  --bg-waves-url: url('data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iYmctd2F2ZXMiIGFyaWEtaGlkZGVuPSJ0cnVlIiB2aWV3Qm94PSIwIDAgMTYwMCAxMDAwIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1heCBzbGljZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZGVmcz4KICAgIDwhLS0gV2FybSBnb2xkZW4gc3Ryb2tlIGZhZGluZyBvdXQgdG93YXJkIHRoZSB1cHBlci1yaWdodCwgY29uY2VudHJhdGluZwogICAgICAgICB0aGUgdGV4dHVyZSBpbiB0aGUgbG93ZXItbGVmdCBxdWFkcmFudC4gQ29sb3IgcGlja2VkIHRvIG1hdGNoIHRoZQogICAgICAgICB3YXJtIGdyZXktYnJvd24gY2FzdCBpbiB0aGUgc291cmNlIG1vY2t1cCdzIGJvdHRvbS1sZWZ0LiAtLT4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0id2F2ZVN0cm9rZSIgeDE9IjAiIHkxPSIxIiB4Mj0iMSIgeTI9IjAuMyI+CiAgICAgIDxzdG9wIG9mZnNldD0iMCUiICBzdG9wLWNvbG9yPSIjYTk4MDU0IiBzdG9wLW9wYWNpdHk9IjAuMzAiLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIzMCUiIHN0b3AtY29sb3I9IiM3YzYwMzgiIHN0b3Atb3BhY2l0eT0iMC4xNSIvPgogICAgICA8c3RvcCBvZmZzZXQ9IjYwJSIgc3RvcC1jb2xvcj0iIzNkMmYxYyIgc3RvcC1vcGFjaXR5PSIwLjA0Ii8+CiAgICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwIi8+CiAgICA8L2xpbmVhckdyYWRpZW50PgogICAgPHJhZGlhbEdyYWRpZW50IGlkPSJ3YXZlTWFzayIgY3g9IjAiIGN5PSIxIiByPSIwLjg1Ij4KICAgICAgPHN0b3Agb2Zmc2V0PSIwJSIgIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgICA8c3RvcCBvZmZzZXQ9IjU1JSIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIwLjQiLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz4KICAgIDwvcmFkaWFsR3JhZGllbnQ+CiAgICA8bWFzayBpZD0iYm90dG9tTGVmdE1hc2siPgogICAgICA8cmVjdCB3aWR0aD0iMTYwMCIgaGVpZ2h0PSIxMDAwIiBmaWxsPSJ1cmwoI3dhdmVNYXNrKSIvPgogICAgPC9tYXNrPgogIDwvZGVmcz4KICA8ZyBmaWxsPSJub25lIiBzdHJva2U9InVybCgjd2F2ZVN0cm9rZSkiIHN0cm9rZS13aWR0aD0iMSIgbWFzaz0idXJsKCNib3R0b21MZWZ0TWFzaykiPgogICAgPHBhdGggZD0iTSAtNDAgOTg1IEMgMjAwIDkwNSwgMzYwIDk1NSwgNjAwIDg4MCBTIDEwMjAgODAwLCAxMjgwIDg1MCBTIDE2NDAgOTA1LCAxNzAwIDg3MCIvPgogICAgPHBhdGggZD0iTSAtNDAgOTUwIEMgMjAwIDg3MCwgMzYwIDkyMCwgNjAwIDg0NSBTIDEwMjAgNzY1LCAxMjgwIDgxNSBTIDE2NDAgODcwLCAxNzAwIDgzNSIvPgogICAgPHBhdGggZD0iTSAtNDAgOTE1IEMgMjAwIDgzNSwgMzYwIDg4NSwgNjAwIDgxMCBTIDEwMjAgNzMwLCAxMjgwIDc4MCBTIDE2NDAgODM1LCAxNzAwIDgwMCIvPgogICAgPHBhdGggZD0iTSAtNDAgODgwIEMgMjAwIDgwMCwgMzYwIDg1MCwgNjAwIDc3NSBTIDEwMjAgNjk1LCAxMjgwIDc0NSBTIDE2NDAgODAwLCAxNzAwIDc2NSIvPgogICAgPHBhdGggZD0iTSAtNDAgODQ1IEMgMjAwIDc2NSwgMzYwIDgxNSwgNjAwIDc0MCBTIDEwMjAgNjYwLCAxMjgwIDcxMCBTIDE2NDAgNzY1LCAxNzAwIDczMCIvPgogICAgPHBhdGggZD0iTSAtNDAgODEwIEMgMjAwIDczMCwgMzYwIDc4MCwgNjAwIDcwNSBTIDEwMjAgNjI1LCAxMjgwIDY3NSBTIDE2NDAgNzMwLCAxNzAwIDY5NSIvPgogICAgPHBhdGggZD0iTSAtNDAgNzc1IEMgMjAwIDY5NSwgMzYwIDc0NSwgNjAwIDY3MCBTIDEwMjAgNTkwLCAxMjgwIDY0MCBTIDE2NDAgNjk1LCAxNzAwIDY2MCIvPgogICAgPHBhdGggZD0iTSAtNDAgNzQwIEMgMjAwIDY2MCwgMzYwIDcxMCwgNjAwIDYzNSBTIDEwMjAgNTU1LCAxMjgwIDYwNSBTIDE2NDAgNjYwLCAxNzAwIDYyNSIvPgogICAgPHBhdGggZD0iTSAtNDAgNzA1IEMgMjAwIDYyNSwgMzYwIDY3NSwgNjAwIDYwMCBTIDEwMjAgNTIwLCAxMjgwIDU3MCBTIDE2NDAgNjI1LCAxNzAwIDU5MCIvPgogICAgPHBhdGggZD0iTSAtNDAgNjcwIEMgMjAwIDU5MCwgMzYwIDY0MCwgNjAwIDU2NSBTIDEwMjAgNDg1LCAxMjgwIDUzNSBTIDE2NDAgNTkwLCAxNzAwIDU1NSIvPgogICAgPHBhdGggZD0iTSAtNDAgNjM1IEMgMjAwIDU1NSwgMzYwIDYwNSwgNjAwIDUzMCBTIDEwMjAgNDUwLCAxMjgwIDUwMCBTIDE2NDAgNTU1LCAxNzAwIDUyMCIvPgogICAgPHBhdGggZD0iTSAtNDAgNjAwIEMgMjAwIDUyMCwgMzYwIDU3MCwgNjAwIDQ5NSBTIDEwMjAgNDE1LCAxMjgwIDQ2NSBTIDE2NDAgNTIwLCAxNzAwIDQ4NSIvPgogIDwvZz4KPC9zdmc+Cg==');

  /* Tell the browser's native form-control UI (autofill background,
     scrollbars, focus rings) to render with the dark palette. Without
     this Chrome paints :-webkit-autofill with its default pale-blue
     overlay regardless of the inset box-shadow override below. */
  color-scheme: dark;

  /* Backgrounds */
  --bg-base:        #0b1424;
  --panel-edge:     rgba(255, 255, 255, 0.06);

  /* Brand gold */
  --gold:           #c9a063;
  --gold-bright:    #e1c089;
  --gold-soft:      rgba(201, 160, 99, 0.18);

  /* Text — softened so the high-luminance cream/silver doesn't
     blow out against the dark navy background. */
  --cream:          #ccc5b4;
  --text:           #b9bec8;
  --muted:          #8a93a4;
  --muted-dim:      #6a7180;

  /* Sidebar + nav meta. --panel-edge-2 is a softer divider (half
     the alpha of --panel-edge); --sidebar-bg is the persistent
     left rail; --pos/--neg/--warn drive the live-data indicators
     next to nav items (theme-independent on purpose so a green
     uptick reads green in both themes). */
  --panel-edge-2:   rgba(255, 255, 255, 0.04);
  --sidebar-bg:     #06101e;
  --pos:            #26d07c;
  --neg:            #ff4d6a;
  --warn:           #f0b400;

  /* Account-page + shared modal/bell/danger tokens. Used by
     /me/account, /watchlists, the sidebar bell popover, and the
     reusable confirm/add modals. */
  --modal-bg:          #11192a;
  --danger-bg:         #6b1f1f;
  --danger-bg-hover:   #842828;
  --danger-fg:         #f5e4e4;
  --warn-text:         #ffb86b;
  --notif-unread-bg:   rgba(201, 160, 99, 0.18);
  --notif-unread-bar:  var(--gold);
  --status-ok:         var(--pos);
  --status-warn:       var(--warn);
  --status-bad:        var(--neg);
  --hero-bg:           linear-gradient(135deg, rgba(28, 42, 70, 0.82) 0%, rgba(18, 28, 50, 0.82) 100%);
  --hero-accent:       rgba(201, 160, 99, 0.45);
  --kpi-bg:            rgba(255, 255, 255, 0.025);
  --kpi-border:        rgba(255, 255, 255, 0.06);
  --pill-bg:           rgba(255, 255, 255, 0.03);
  --rule:              rgba(255, 255, 255, 0.08);

  /* Wordmark shadow — single soft drop layer, kept minimal so the
     wordmark feels grounded without competing with the SVG logo's
     own emboss/drop shadow next to it. */
  --wordmark-shadow: 0 1px 2px rgba(0, 0, 0, 0.32);

  /* Landing-page heading tone — slightly lighter than --cream, tuned
     toward the SVG logo's pewter highlights so the wordmark reads as
     part of the same visual family as the mark next to it. Also
     reused as the Sign In button text colour. Scoped — does NOT
     replace --cream on the dashboard or anywhere else. */
  --landing-heading: #d2cbb7;

  /* Fields */
  --field-bg:       #0d1626;
  --field-bg-focus: #0e1828;
  --field-border:   rgba(255, 255, 255, 0.07);
  --field-border-focus: rgba(201, 160, 99, 0.55);

  /* Composite tokens */
  --waves-blend:    screen;
  --waves-opacity:  0.5;

  --bg-gradient:
    radial-gradient(110% 95% at 0% 100%,
      rgba(168, 128, 78, 0.28) 0%,
      rgba(120, 92, 56, 0.16) 18%,
      rgba(60, 48, 30, 0.06) 38%,
      rgba(0, 0, 0, 0) 62%),
    linear-gradient(180deg, #0a131f 0%, #0c1521 45%, #0d1620 100%);

  --card-bg:
    linear-gradient(180deg, rgba(22, 33, 56, 0.85) 0%, rgba(16, 25, 45, 0.85) 100%);
  --card-shadow: 0 30px 70px rgba(0, 0, 0, 0.45);

  --btn-bg:         linear-gradient(180deg, #d4ad6e 0%, #c19a5e 100%);
  --btn-fg:         #1a1410;
  --btn-shadow:
    0 1px 0 rgba(255, 255, 255, 0.18) inset,
    0 -1px 0 rgba(0, 0, 0, 0.15) inset,
    0 12px 24px rgba(0, 0, 0, 0.35);

  --logo-shadow:    drop-shadow(0 18px 35px rgba(0, 0, 0, 0.55));

  --success-fg:     #34d399;
  --success-border: #34d399;
  --error-fg:       #ff6b6b;
}

/* Light overrides — applied two ways */
:root[data-theme="light"],
:root.is-light {
  color-scheme: light;

  --bg-base:        #f4efe3;
  --panel-edge:     rgba(40, 30, 15, 0.10);

  --gold:           #b88944;
  --gold-bright:    #8e6628;
  --gold-soft:      rgba(184, 137, 68, 0.14);

  /* Softened to avoid near-black on cream. Heading stays darker than
     the muted blurb (#6b665b) but reads as warm dark gray, not black. */
  --cream:          #443c33;
  --text:           #4f4538;
  --muted:          #6b665b;
  --muted-dim:      #8a8478;

  --panel-edge-2:   rgba(40, 30, 15, 0.05);
  --sidebar-bg:     #ebe5d6;

  /* Light-theme variants of the account/modal tokens. */
  --modal-bg:          #fbf6e8;
  --danger-bg:         #b94747;
  --danger-bg-hover:   #a23a3a;
  --danger-fg:         #ffffff;
  --warn-text:         #b8651e;
  --notif-unread-bg:   rgba(184, 137, 68, 0.12);
  --notif-unread-bar:  var(--gold);
  --hero-bg:           linear-gradient(135deg, rgba(255, 250, 238, 0.96) 0%, rgba(248, 242, 226, 0.96) 100%);
  --hero-accent:       rgba(184, 137, 68, 0.45);
  --kpi-bg:            rgba(40, 30, 15, 0.03);
  --kpi-border:        rgba(40, 30, 15, 0.06);
  --pill-bg:           rgba(40, 30, 15, 0.04);
  --rule:              rgba(40, 30, 15, 0.10);

  /* Minimal warm drop on cream — barely-there so the wordmark feels
     grounded without an obvious emboss. */
  --wordmark-shadow: 0 1px 1px rgba(80, 50, 20, 0.18);

  /* Landing heading on light theme — slightly lighter than --cream
     (#443c33), leaning toward the logo's silver-shadow tone. */
  --landing-heading: #524940;

  --field-bg:       #eee7d6;
  --field-bg-focus: #f6f0df;
  --field-border:   rgba(40, 30, 15, 0.10);
  --field-border-focus: rgba(184, 137, 68, 0.55);

  --waves-blend:    multiply;
  --waves-opacity:  0.45;

  --bg-gradient:
    radial-gradient(110% 95% at 0% 100%,
      rgba(200, 160, 90, 0.22) 0%,
      rgba(180, 140, 70, 0.10) 18%,
      rgba(120, 90, 50, 0.04) 38%,
      rgba(0, 0, 0, 0) 62%),
    linear-gradient(180deg, #f4efe3 0%, #f0e9d8 45%, #ebe5d7 100%);

  --card-bg:
    linear-gradient(180deg, rgba(255, 255, 255, 0.94) 0%, rgba(250, 246, 234, 0.94) 100%);
  --card-shadow:    0 28px 60px rgba(80, 60, 30, 0.18);

  --btn-bg:         linear-gradient(180deg, #d4ad6e 0%, #b88a4a 100%);
  --btn-fg:         #1a1410;
  --btn-shadow:
    0 1px 0 rgba(255, 255, 255, 0.45) inset,
    0 -1px 0 rgba(0, 0, 0, 0.12) inset,
    0 10px 22px rgba(80, 60, 30, 0.18);

  --logo-shadow:    drop-shadow(0 14px 28px rgba(60, 40, 10, 0.22));

  --success-fg:     #0f7a4f;
  --success-border: #4caf80;
  --error-fg:       #b3261e;
}

/* OS-pref tracking: when user hasn't picked, follow the OS. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) {
    color-scheme: light;

    --bg-base:        #f4efe3;
    --panel-edge:     rgba(40, 30, 15, 0.10);

    --gold:           #b88944;
    --gold-bright:    #8e6628;
    --gold-soft:      rgba(184, 137, 68, 0.14);

    --cream:          #443c33;
    --text:           #4f4538;
    --muted:          #6b665b;
    --muted-dim:      #8a8478;

    --panel-edge-2:   rgba(40, 30, 15, 0.05);
    --sidebar-bg:     #ebe5d6;

    --modal-bg:          #fbf6e8;
    --danger-bg:         #b94747;
    --danger-bg-hover:   #a23a3a;
    --danger-fg:         #ffffff;
    --warn-text:         #b8651e;
    --notif-unread-bg:   rgba(184, 137, 68, 0.12);
    --notif-unread-bar:  var(--gold);
    --hero-bg:           linear-gradient(135deg, rgba(255, 250, 238, 0.96) 0%, rgba(248, 242, 226, 0.96) 100%);
    --hero-accent:       rgba(184, 137, 68, 0.45);
    --kpi-bg:            rgba(40, 30, 15, 0.03);
    --kpi-border:        rgba(40, 30, 15, 0.06);
    --pill-bg:           rgba(40, 30, 15, 0.04);
    --rule:              rgba(40, 30, 15, 0.10);

    --wordmark-shadow: 0 1px 1px rgba(80, 50, 20, 0.18);
    --landing-heading: #524940;

    --field-bg:       #eee7d6;
    --field-bg-focus: #f6f0df;
    --field-border:   rgba(40, 30, 15, 0.10);
    --field-border-focus: rgba(184, 137, 68, 0.55);

    --waves-blend:    multiply;
    --waves-opacity:  0.45;

    --bg-gradient:
      radial-gradient(110% 95% at 0% 100%,
        rgba(200, 160, 90, 0.22) 0%,
        rgba(180, 140, 70, 0.10) 18%,
        rgba(120, 90, 50, 0.04) 38%,
        rgba(0, 0, 0, 0) 62%),
      linear-gradient(180deg, #f4efe3 0%, #f0e9d8 45%, #ebe5d7 100%);

    --card-bg:
      linear-gradient(180deg, rgba(255, 255, 255, 0.94) 0%, rgba(250, 246, 234, 0.94) 100%);
    --card-shadow:    0 28px 60px rgba(80, 60, 30, 0.18);

    --btn-bg:         linear-gradient(180deg, #d4ad6e 0%, #b88a4a 100%);
    --btn-shadow:
      0 1px 0 rgba(255, 255, 255, 0.45) inset,
      0 -1px 0 rgba(0, 0, 0, 0.12) inset,
      0 10px 22px rgba(80, 60, 30, 0.18);

    --logo-shadow:    drop-shadow(0 14px 28px rgba(60, 40, 10, 0.22));

    --success-fg:     #0f7a4f;
    --success-border: #4caf80;
    --error-fg:       #b3261e;
  }
}

/* ============================================================
   Text selection — Chromium's default ::selection is a pale
   blue overlay. Per the gemini consult, Chromium can briefly
   select credential text on submit (to hand off to its internal
   password manager). That selection paint sits in a layer that
   the autofill-suppression CSS cannot reach. Theming ::selection
   directly so the highlight is gold-on-cream instead of blue.
   ============================================================ */
::selection {
  background-color: rgba(201, 160, 99, 0.40);
  color: var(--cream);
}
::-moz-selection {
  background-color: rgba(201, 160, 99, 0.40);
  color: var(--cream);
}

/* ============================================================
   Reset + base
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; min-height: 100%; }

/* Suppress transitions during initial paint. The head <script> adds
   `theme-init` to <html>; login.js removes it after first paint. This
   prevents inputs from animating from user-agent defaults to themed
   values when the page first renders (was visible as a "black flash"
   on form fields). */
:root.theme-init *,
:root.theme-init *::before,
:root.theme-init *::after {
  transition: none !important;
  animation-duration: 0s !important;
}
body {
  font-family: var(--sans);
  color: var(--text);
  background: var(--bg-base);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  font-weight: 500;
  /* Native form-control accent (checkboxes, radios, range, progress). */
  accent-color: var(--gold);
}

/* ============================================================
   Background stack
   ============================================================ */
.bg-stack {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: var(--bg-gradient);
}
.bg-waves {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background-image: var(--bg-waves-url);
  background-repeat: no-repeat;
  background-position: left bottom;
  background-size: cover;
  opacity: var(--waves-opacity);
  mix-blend-mode: var(--waves-blend);
}

/* ============================================================
   Shell + topbar
   ============================================================ */
.shell {
  position: relative;
  z-index: 2;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 22px 48px 0;
  gap: 16px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  color: var(--cream);
}
.brand-mark {
  width: 32px;
  height: 32px;
  display: block;
  background-image: var(--mm-logo-flat-url);
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.35));
}

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

/* Theme toggle */
.theme-toggle {
  appearance: none;
  background: transparent;
  border: 1px solid var(--panel-edge);
  border-radius: 8px;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.theme-toggle:hover {
  color: var(--gold);
  border-color: var(--gold-soft);
  background: var(--gold-soft);
}
.theme-toggle .ti {
  width: 18px;
  height: 18px;
  display: none;
}
/* Drive icon visibility from <html data-theme>, set synchronously by
   the head script BEFORE first paint — not from data-mode on the
   button, which login.js sets late (the script is deferred). Driving
   off data-mode caused a refresh flash where the button briefly
   rendered with both icons hidden until login.js ran.
   Default = dark (no data-theme + dark OS) → moon. */
.theme-toggle .ti-moon { display: block; }

:root[data-theme="dark"]  .theme-toggle .ti-moon { display: block; }
:root[data-theme="dark"]  .theme-toggle .ti-sun  { display: none; }
:root[data-theme="light"] .theme-toggle .ti-moon { display: none; }
:root[data-theme="light"] .theme-toggle .ti-sun  { display: block; }

/* "Auto" mode (no stored choice → no data-theme attribute) +
   light OS preference → show sun. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) .theme-toggle .ti-moon { display: none; }
  :root:not([data-theme]) .theme-toggle .ti-sun  { display: block; }
}

/* ============================================================
   Main layouts
   ============================================================ */
main {
  flex: 1;
  width: 100%;
  margin: 0 auto;
}

/* Two-column landing layout (login.html) */
body[data-page="login"] main {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 64px;
  padding: 40px 80px 80px;
  align-items: center;
  max-width: 1480px;
}

/* Centered card layout (mfa, forgot, reset) */
body[data-page="auth-mfa"] main,
body[data-page="auth-forgot"] main,
body[data-page="auth-reset"] main {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 28px 80px;
  min-height: calc(100vh - 80px);
}

/* ============================================================
   Hero (left side of login)
   ============================================================ */
.hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 0 8px;
}
.hero-logo {
  width: 280px;
  aspect-ratio: 1162 / 1064;
  display: block;
  margin-bottom: 28px;
  background-image: var(--mm-logo-url);
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  filter: var(--logo-shadow);
}
.wordmark {
  font-family: var(--sans);
  /* 500 (Kräftig) — same weight as the body so the wordmark reads
     as elegant brand type rather than a heavy display heading.
     Emboss text-shadow + lighter --landing-heading colour match the
     SVG logo's raised-metal feel and pewter tone. */
  font-weight: 500;
  font-size: 72px;
  line-height: 1;
  letter-spacing: 0.005em;
  color: var(--landing-heading);
  margin: 0 0 22px;
  text-shadow: var(--wordmark-shadow);
}
.tagline {
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 600;
  color: var(--gold);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin: 0 0 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
}
.tagline::before,
.tagline::after {
  content: "";
  display: block;
  width: 36px;
  height: 1px;
  background: var(--gold);
  opacity: 0.85;
}
.blurb {
  font-family: var(--sans);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.65;
  color: var(--muted);
  max-width: 440px;
  margin: 0;
}

/* ============================================================
   Card (sign-in / MFA / reset / forgot)
   ============================================================ */
.card {
  background: var(--card-bg);
  border: 1px solid var(--panel-edge);
  border-radius: 14px;
  padding: 44px 44px 40px;
  width: 100%;
  max-width: 460px;
  box-shadow: var(--card-shadow);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
body[data-page="login"] .card {
  justify-self: end;
  margin-right: 73px;
}

.card h2,
.card h1 {
  font-family: var(--sans);
  /* 500 (Kräftig) — paired with the 500-weight landing wordmark so the
     card heading reads as part of the same display hierarchy.
     Uses --landing-heading (lighter than --cream, logo-tuned) so the
     card and wordmark share the same pewter tonality. */
  font-weight: 500;
  font-size: 38px;
  line-height: 1.05;
  color: var(--landing-heading);
  margin: 0 0 10px;
  letter-spacing: 0.005em;
}
.card .sub {
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 500;
  color: var(--muted);
  margin: 0 0 28px;
}

/* Small centered-card variant uses a brand block at the top
   (logo + heading) for visual consistency with login.html. */
.card .brand-row {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0 0 18px;
}
.card .brand-row img {
  width: 40px;
  height: 40px;
  display: block;
  filter: var(--logo-shadow);
}

/* ============================================================
   Form: labels, fields, buttons
   ============================================================ */
label {
  display: block;
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text);
  margin: 18px 0 8px;
}

.field {
  position: relative;
  display: flex;
  align-items: center;
  background: var(--field-bg);
  border: 1px solid var(--field-border);
  border-radius: 8px;
  /* Only border-color transitions on focus — theme/background swaps are
     instant so they don't animate through user-agent default colours. */
  transition: border-color 0.15s ease;
}
.field:focus-within {
  border-color: var(--field-border-focus);
  background: var(--field-bg-focus);
}
.field .icon {
  width: 18px;
  height: 18px;
  margin: 0 12px 0 14px;
  color: var(--muted-dim);
  flex-shrink: 0;
}
.field input {
  flex: 1;
  background: transparent;
  border: 0;
  outline: none;
  color: var(--text);
  font-family: var(--sans);
  /* 16px to defeat iOS Safari zoom-on-focus (any value <16px
     triggers the viewport zoom on input focus). */
  font-size: 16px;
  font-weight: 500;
  padding: 12px 14px 12px 0;
  width: 100%;
}
.field input::placeholder { color: var(--muted-dim); }

/* Bare .input fallback for forms that don't wrap fields in .field.
   Used by the password-change form on /me/account, the add-channel
   modal, the MFA-verify modal. Tighter padding than .field input
   (which lives in the login-card chrome where bigger fields are
   intentional). */
.input {
  display: block;
  width: 100%;
  background: var(--field-bg);
  border: 1px solid var(--field-border);
  border-radius: 8px;
  color: var(--text);
  font-family: var(--sans);
  /* 16px to defeat iOS Safari zoom-on-focus. */
  font-size: 16px;
  font-weight: 500;
  padding: 9px 12px;
  outline: none;
  transition: border-color 0.15s ease;
}
.input:focus {
  border-color: var(--field-border-focus);
  background: var(--field-bg-focus);
}
.input::placeholder { color: var(--muted-dim); }

/* ============================================================
   Suppress browser autofill colours (the "flash blue" after the
   browser or password manager fills email / password / OTP code).
   Chromium paints :-webkit-autofill with a pale-blue background
   via a special path that ignores `background-color`; the inset
   box-shadow is the canonical override. We also force the input's
   own background-color so the shadow has an opaque surface (the
   .field input was relying on its transparent wrapper, which let
   Chromium's blue layer show through).

   !important everywhere because Chromium's autofill paint sits at
   high specificity in the UA shadow tree. Selectors cover:
     - :-webkit-autofill            (Chromium prefixed)
     - :autofill                    (standard, Chromium + Firefox + Safari)
     - :-internal-autofill-selected (Chromium internal, mid-capture)
     - :-internal-autofill-previewed (Chromium internal, suggestion preview)
   ============================================================ */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active,
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus,
.field input:-webkit-autofill:active,
input:autofill,
input:autofill:hover,
input:autofill:focus,
.field input:autofill,
.input:autofill {
  -webkit-box-shadow: 0 0 0 1000px var(--field-bg) inset !important;
          box-shadow: 0 0 0 1000px var(--field-bg) inset !important;
  -webkit-text-fill-color: var(--text) !important;
  caret-color: var(--text) !important;
  background-color: var(--field-bg) !important;
  background-image: none !important;
  background-clip: padding-box !important;
  color: var(--text) !important;
  border-color: var(--field-border) !important;
  transition: background-color 5000s ease-in-out 0s,
              color            5000s ease-in-out 0s !important;
}

/* Focused state — both .field-wrapped and bare .input variants. */
.field:focus-within input:-webkit-autofill,
.field:focus-within input:autofill,
.input:focus:-webkit-autofill,
.input:focus:autofill {
  -webkit-box-shadow: 0 0 0 1000px var(--field-bg-focus) inset !important;
          box-shadow: 0 0 0 1000px var(--field-bg-focus) inset !important;
  background-color: var(--field-bg-focus) !important;
  border-color: var(--field-border-focus) !important;
}

/* Chromium-internal pseudo-classes covering the brief moments
   between "user submitted" and "Chrome captured", and between
   "Chrome suggested" and "user picked". */
input:-internal-autofill-selected,
input:-internal-autofill-previewed,
.field input:-internal-autofill-selected,
.field input:-internal-autofill-previewed,
.input:-internal-autofill-selected,
.input:-internal-autofill-previewed {
  -webkit-box-shadow: 0 0 0 1000px var(--field-bg) inset !important;
          box-shadow: 0 0 0 1000px var(--field-bg) inset !important;
  -webkit-text-fill-color: var(--text) !important;
  background-color: var(--field-bg) !important;
  background-image: none !important;
  color: var(--text) !important;
}

/* ============================================================
   1Password 8 "highlight filled fields" override.
   When 1Password fills a field it marks the input with the
   data-com-onepassword-filled attribute (value "light" or "dark").
   1Password paints a translucent overlay on the field; we override
   it at three layers:
     - the input itself (background + inset shadow + text fill)
     - the .field wrapper via :has() (1P's overlay sits over the
       wrapper, so we restore its bg)
     - the .pw-wrap variant for bare .input fields with siblings
   :has() is Chromium 105+, Safari 15.4+, Firefox 121+ — all the
   browsers we target. Falls back to a no-op on older browsers.
   If 1Password paints via Shadow DOM (out of CSS reach), this
   will be a graceful no-op and the user needs to disable the
   feature in 1Password's settings instead.
   ============================================================ */
input[data-com-onepassword-filled],
input[data-com-onepassword-filled="light"],
input[data-com-onepassword-filled="dark"],
.field input[data-com-onepassword-filled],
.input[data-com-onepassword-filled] {
  background-color: var(--field-bg) !important;
  background-image: none !important;
  -webkit-box-shadow: 0 0 0 1000px var(--field-bg) inset !important;
          box-shadow: 0 0 0 1000px var(--field-bg) inset !important;
  -webkit-text-fill-color: var(--text) !important;
  color: var(--text) !important;
  caret-color: var(--text) !important;
}

.field:has(input[data-com-onepassword-filled]) {
  background-color: var(--field-bg) !important;
}
.field:focus-within:has(input[data-com-onepassword-filled]) {
  background-color: var(--field-bg-focus) !important;
}
.field:has(input[data-com-onepassword-filled]) input {
  background-color: var(--field-bg) !important;
  -webkit-box-shadow: 0 0 0 1000px var(--field-bg) inset !important;
          box-shadow: 0 0 0 1000px var(--field-bg) inset !important;
}

.pw-toggle,
.eye-btn {
  appearance: none;
  background: transparent;
  border: 0;
  cursor: pointer;
  color: var(--muted-dim);
  padding: 6px 14px 6px 8px;
  display: inline-flex;
  align-items: center;
  transition: color 0.15s ease;
}
.pw-toggle svg,
.eye-btn svg {
  width: 20px;
  height: 20px;
}
.pw-toggle:hover,
.eye-btn:hover { color: var(--gold); }

/* Password input that's not wrapped in .field — used by auth_reset */
.pw-wrap {
  position: relative;
}
.pw-wrap .pw-toggle {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
}
.pw-wrap .input { padding-right: 44px; }

.row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 22px 0 24px;
}

.forgot,
a.text-link {
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 600;
  color: var(--gold);
  text-decoration: none;
}
.forgot:hover,
a.text-link:hover { color: var(--gold-bright); }

.signin-btn,
.btn {
  width: 100%;
  display: block;
  background: var(--btn-bg);
  /* Fixed warm pewter (the light-theme --landing-heading value) for
     both themes so the button text reads with solid contrast against
     the gold gradient regardless of theme. Theme-switching to the
     pewter-cream on dark made the label wash out on gold because the
     cream and gold are too close in luminance. */
  color: #4a4136;
  border: 0;
  border-radius: 8px;
  padding: 14px 16px;
  font-family: var(--sans);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  box-shadow: var(--btn-shadow);
  transition: filter 0.15s ease, transform 0.05s ease;
  margin-top: 8px;
}
.signin-btn:hover,
.btn:hover { filter: brightness(1.05); }
.signin-btn:active,
.btn:active { transform: translateY(1px); }
.signin-btn[aria-busy="true"],
.btn[aria-busy="true"],
.signin-btn:disabled,
.btn:disabled { filter: grayscale(0.2) brightness(0.85); cursor: not-allowed; }

/* Button variants — same geometry as .btn, just different colour
   treatment. Reused on the account page (Regenerate codes, Disable
   MFA, Disable channel, Revoke session, etc.) and on /watchlists. */
.btn-secondary {
  display: inline-block;
  background: transparent;
  color: var(--text);
  border: 1px solid var(--panel-edge);
  border-radius: 8px;
  padding: 10px 16px;
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  box-shadow: none;
  transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}
.btn-secondary:hover {
  color: var(--gold);
  border-color: var(--gold-soft);
  background: var(--gold-soft);
}
.btn-danger {
  display: inline-block;
  background: var(--danger-bg);
  color: var(--danger-fg);
  border: 0;
  border-radius: 8px;
  padding: 10px 16px;
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  box-shadow: none;
  transition: background-color 0.15s ease, filter 0.15s ease;
}
.btn-danger:hover { background: var(--danger-bg-hover); }
.btn-sm { padding: 6px 12px; font-size: 12.5px; }
.btn-row { display: flex; flex-wrap: wrap; gap: 8px; padding-top: 4px; }

/* ============================================================
   Reusable modal — used for confirm-disable, channel-add, and any
   future modal flow. Backdrop + centered card, focus-trap via JS.
   Hidden by default; toggled with the [hidden] attribute or by
   adding/removing .is-open on the backdrop.
   ============================================================ */
.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
:root[data-theme="light"] .modal-backdrop { background: rgba(40, 30, 15, 0.35); }
.modal-backdrop[hidden] { display: none; }
.modal {
  background: var(--modal-bg);
  border: 1px solid var(--panel-edge);
  border-radius: 14px;
  width: 100%;
  max-width: 460px;
  box-shadow: var(--card-shadow);
  padding: 22px 24px 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.modal-title {
  font-family: var(--sans);
  font-weight: 600;
  font-size: 17px;
  color: var(--cream);
  margin: 0;
}
.modal-close {
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--muted);
  width: 26px;
  height: 26px;
  border-radius: 6px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s ease, background-color 0.15s ease;
}
.modal-close:hover { color: var(--cream); background: var(--panel-edge-2); }
.modal-close svg { width: 14px; height: 14px; }
.modal-body { display: flex; flex-direction: column; gap: 10px; }
.modal-body p { margin: 0; line-height: 1.55; color: var(--text); font-size: 14px; }
.modal-body p.muted { color: var(--muted); font-size: 13px; }
.modal-foot {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 4px;
}

/* ============================================================
   Sidebar bell + notifications popover. Shared across pages that
   include the sidebar (dashboard, account, watchlists, future).
   Lives next to the brand-link as an alternate occupant of the
   header-row's optional slot.
   ============================================================ */
.sidebar-bell {
  position: relative;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  flex-shrink: 0;
  transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}
.sidebar-bell:hover {
  color: var(--cream);
  background: var(--panel-edge-2);
  border-color: var(--panel-edge);
}
.sidebar-bell svg { width: 16px; height: 16px; }
.sidebar-bell.has-unread::after {
  content: "";
  position: absolute;
  top: 4px;
  right: 4px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 0 2px var(--sidebar-bg);
}

.notif-popover {
  position: fixed;
  top: 50px;
  left: 250px;
  /* Width matches the mockup (ideas/mockups/2026-05/account-mockup_3.html
     line 276). The earlier 400px + min-width 400 + width:!important
     stack was over-engineered noise from the Brave debugging round —
     the actual fix is the flex-not-grid .notif row below. */
  width: 360px;
  max-width: calc(100vw - 32px);
  max-height: calc(100vh - 80px);
  background: var(--card-bg);
  border: 1px solid var(--panel-edge);
  border-radius: 12px;
  box-shadow: var(--card-shadow);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  z-index: 50;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.notif-popover[hidden] { display: none; }
.notif-popover::before {
  content: "";
  position: absolute;
  top: -6px;
  left: -6px;
  width: 12px;
  height: 12px;
  background: var(--card-bg);
  border-top: 1px solid var(--panel-edge);
  border-left: 1px solid var(--panel-edge);
  transform: rotate(45deg);
}
.notif-popover-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 13px 14px;
  border-bottom: 1px solid var(--rule);
}
.notif-popover-title {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 14px;
  color: var(--cream);
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.notif-popover-title .unread-badge {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  color: var(--gold-bright);
  background: var(--gold-soft);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: 4px;
}
.notif-popover-title .unread-badge[hidden] { display: none; }
.notif-popover-close {
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--muted);
  width: 22px;
  height: 22px;
  border-radius: 5px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s ease, background-color 0.15s ease;
}
.notif-popover-close:hover { color: var(--cream); background: var(--panel-edge-2); }
.notif-popover-close svg { width: 13px; height: 13px; }
.notif-popover-body {
  flex: 1;
  overflow-y: auto;
  padding: 2px 0;
}
.notif-popover-empty {
  padding: 28px 18px;
  text-align: center;
  font-size: 13px;
  color: var(--muted);
}
.notif-popover .notif {
  /* Flex (not grid — grid kept biting us). position:relative so the
     unread bar (absolute-positioned ::before) anchors to this row. */
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 10px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--rule);
  width: 100%;
  box-sizing: border-box;
}
.notif-popover .notif:last-of-type { border-bottom: 0; }
.notif-popover .notif.unread { background: var(--notif-unread-bg); }
/* Unread indicator bar — absolutely-positioned ::before so it sits
   14px in from the row's outer left edge (matching the mockup's
   `padding-left: 14px; grid-template-columns: 3px 1fr` placement).
   This replaces the previous border-left approach, which painted
   flush against the row's outer edge with no inset. */
.notif-popover .notif.unread::before {
  /* Inset top/bottom by 11px to match the row's vertical padding.
     In the mockup the bar lives inside the grid cell, which excludes
     the row padding, so the bar is shorter than the row's full
     height. */
  content: "";
  position: absolute;
  left: 14px;
  top: 11px;
  bottom: 11px;
  width: 3px;
  background: var(--notif-unread-bar);
  border-radius: 2px;
}
/* Legacy <span class="notif-bar"> emitted by notifItemHtml — hide so
   it doesn't take a flex slot. */
.notif-popover .notif-bar { display: none; }
.notif-popover .notif-body {
  /* Flex item: take all remaining width past the bar's visual slot.
     padding-left reserves space for the absolute-positioned unread
     bar (3px wide at left:14px) plus a 10px gap between bar and
     content — matches the mockup's grid `3px 1fr gap:10` spacing.
     Applied to BOTH read and unread rows so toggling read state
     doesn't shift content horizontally.
     min-width: 0 lets nowrap+ellipsis on the title actually clip
     instead of expanding the flex item to its intrinsic content
     width (the default flex min-width:auto behaviour). */
  flex: 1 1 0;
  min-width: 0;
  padding-left: 13px;
}
.notif-popover .notif-title {
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--cream);
  margin: 0 0 2px;
  /* Single line, ellipsis if too long for the popover. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.notif-popover .notif-text {
  font-family: var(--sans);
  font-size: 12.5px;
  color: var(--text);
  margin: 0 0 4px;
  line-height: 1.45;
  /* 2-line clamp, ellipsis on overflow. Keeps each row a stable
     height so the popover doesn't expand off-screen on long messages. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.notif-popover .notif-ts {
  font-family: var(--sans);
  font-size: 10.5px;
  color: var(--muted-dim);
  letter-spacing: 0.02em;
}
.notif-popover-foot {
  padding: 10px 14px;
  border-top: 1px solid var(--rule);
  text-align: center;
  background: var(--panel-edge-2);
}
.notif-popover-foot a {
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--gold);
  text-decoration: none;
  padding: 5px 10px;
  border-radius: 6px;
  transition: color 0.15s ease, background-color 0.15s ease;
}
.notif-popover-foot a:hover { color: var(--gold-bright); background: var(--gold-soft); }

/* ============================================================
   Errors + banners
   ============================================================ */
.error {
  display: none;
  margin-top: 14px;
  padding: 10px 12px;
  border: 1px solid var(--error-fg);
  color: var(--error-fg);
  border-radius: 6px;
  font-size: 13.5px;
  font-weight: 500;
}
.error.show,
.error[style*="block"] { display: block; }

.banner-success {
  margin-top: 14px;
  padding: 10px 12px;
  border: 1px solid var(--success-border);
  color: var(--success-fg);
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
}

.footer-link {
  margin-top: 18px;
  font-size: 13px;
  color: var(--muted);
  text-align: left;
}

form { margin: 0; }

/* ============================================================
   Primary site nav (used on /dashboard, designed to be reusable
   on other in-app pages later). Visual feel matches the theme
   toggle: 1px panel-edge border, transparent bg, gold accent on
   hover + stronger gold on the active item.
   ============================================================ */
.primary-nav {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1;
  justify-content: center;
  flex-wrap: wrap;
  margin: 0 24px;
}
.nav-link {
  display: inline-flex;
  align-items: center;
  padding: 7px 14px;
  border: 1px solid var(--panel-edge);
  border-radius: 8px;
  background: transparent;
  color: var(--text);
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.nav-link:hover {
  color: var(--gold);
  border-color: var(--gold-soft);
  background: var(--gold-soft);
}
.nav-link.active {
  color: var(--gold-bright);
  border-color: var(--gold);
  background: var(--gold-soft);
}

/* Logout button in topbar — visually subordinate to the nav,
   same border treatment but text-only (no gold highlight). */
.logout-form { margin: 0; }
.logout-btn {
  appearance: none;
  background: transparent;
  border: 1px solid var(--panel-edge);
  border-radius: 8px;
  padding: 7px 14px;
  color: var(--muted);
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.logout-btn:hover {
  color: var(--gold);
  border-color: var(--gold-soft);
  background: var(--gold-soft);
}

/* ============================================================
   Dashboard layout (stub). Placeholder cards in a responsive
   grid; each card is meant to be replaced one-by-one as the
   underlying features land (sector news digest, rotation
   snapshot, newsletter highlights, top movers).
   ============================================================ */
.dashboard-main {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 40px 28px 80px;
}
.dashboard-head {
  margin: 0 0 28px;
}
.dashboard-head h1 {
  font-family: var(--sans);
  font-weight: 600;
  font-size: 36px;
  line-height: 1.05;
  color: var(--cream);
  letter-spacing: 0.005em;
  margin: 0 0 8px;
}
.dashboard-head .sub {
  font-family: var(--sans);
  font-size: 14.5px;
  font-weight: 500;
  color: var(--muted);
  max-width: 720px;
  margin: 0;
  line-height: 1.55;
}
.dashboard-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 18px;
}
.dashboard-card {
  background: var(--card-bg);
  border: 1px solid var(--panel-edge);
  border-radius: 14px;
  padding: 22px 24px 24px;
  box-shadow: var(--card-shadow);
  /* backdrop-filter removed 2026-06-02: shared chrome across dashboard.
     Many cards visible during scroll × per-frame Gaussian blur. Same
     fix as newsletters .panel (#339) and account .panel. */
  min-height: 160px;
  display: flex;
  flex-direction: column;
}
.dashboard-card > header {
  margin: 0 0 6px;
}
.dashboard-card h2 {
  font-family: var(--sans);
  font-weight: 600;
  font-size: 18px;
  letter-spacing: 0.005em;
  color: var(--cream);
  margin: 0;
}
.dashboard-card .muted {
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 500;
  color: var(--muted);
  margin: 4px 0 0;
  line-height: 1.5;
}
.dashboard-card .placeholder {
  margin-top: auto;
  padding-top: 14px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-dim);
}

/* Tighter nav layout on narrow viewports — nav can wrap below
   the brand+toggle row if it has to. */
@media (max-width: 880px) {
  body[data-page="dashboard"] .topbar { flex-wrap: wrap; gap: 12px 16px; }
  body[data-page="dashboard"] .primary-nav {
    order: 3;
    width: 100%;
    margin: 0;
    justify-content: flex-start;
  }
}

/* ============================================================
   Dashboard sidebar shell.
   Persistent 240px left rail with brand block + nav list + footer
   (account / theme toggle / logout). On mobile (≤760px) the
   sidebar becomes a slide-out drawer toggled via body[data-nav-open].
   Active route + meta-cell rendering is wired in dashboard.html.
   ============================================================ */
/* .app-shell is shared chrome across every in-app page that uses the
   sidebar (dashboard, /me/account, /watchlists, …). The grid template
   columns shrink to a 56px rail when <html data-sidebar="collapsed">
   is set — toggled by the sidebar-toggle button + persisted in
   localStorage. transition keeps the snap smooth. */
/* The sidebar is now position:fixed (see .sidebar below), so .app-shell is
   just a block wrapper around the page's <main>. Page content is offset to
   clear the fixed rail + market bar via body padding keyed on
   <html data-chrome="on"> — see the "Unified chrome offsets" block further
   down. (Was a 2-col grid; the grid let the sidebar scroll away because it
   was only sticky within its grid cell.) */
.app-shell {
  position: relative;
  z-index: 2;
  min-height: 100vh;
}

/* Sidebar toggle button — lives in the sidebar-footer-actions row,
   between theme-toggle and the sign-out form. Same icon-button
   treatment as theme-toggle. Hides on mobile (drawer pattern there). */
.sidebar-toggle {
  appearance: none;
  background: transparent;
  border: 1px solid var(--panel-edge);
  border-radius: 7px;
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  cursor: pointer;
  flex-shrink: 0;
  transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}
.sidebar-toggle:hover {
  color: var(--gold);
  border-color: var(--gold-soft);
  background: var(--gold-soft);
}
.sidebar-toggle svg { width: 14px; height: 14px; }
.sidebar-toggle .chev-right { display: none; }
:root[data-sidebar="collapsed"] .sidebar-toggle .chev-left  { display: none; }
:root[data-sidebar="collapsed"] .sidebar-toggle .chev-right { display: block; }

/* Collapsed-sidebar element visibility. Each rule hides what doesn't
   fit in 56px and re-centers what's left. The brand stacks vertically:
   M logo on top, bell directly under it (still clickable to open the
   notifications popover — which positions itself dynamically). */
:root[data-sidebar="collapsed"] .sidebar-inner    { padding: 14px 6px 10px; }
:root[data-sidebar="collapsed"] .sidebar-brand    {
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;
  padding: 8px 0 14px;
  gap: 10px;
  min-height: 36px;
}
:root[data-sidebar="collapsed"] .sidebar-brand .brand-link {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  min-width: 0;
}
:root[data-sidebar="collapsed"] .sidebar-brand .brand-mark {
  width: 26px;
  height: 26px;
  display: block;
}
:root[data-sidebar="collapsed"] .brand-wordmark   { display: none; }
/* Bell stays visible under the logo — same 26x26 hit target, no
   negative offset, sits directly below the M. */
:root[data-sidebar="collapsed"] .sidebar-bell     { margin: 0; }
:root[data-sidebar="collapsed"] .nav-item         { justify-content: center; padding: 6px 0; gap: 0; }
:root[data-sidebar="collapsed"] .nav-label        { display: none; }
:root[data-sidebar="collapsed"] .nav-meta         { display: none; }
:root[data-sidebar="collapsed"] .account-block    { justify-content: center; padding: 4px 0; }
:root[data-sidebar="collapsed"] .account-info     { display: none; }
:root[data-sidebar="collapsed"] .sidebar-footer-actions {
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
}
:root[data-sidebar="collapsed"] .logout-form      { display: none; }

/* Active-route indicator (gold left bar) for nav items needs a tweak
   in collapsed mode — without padding the ::before pseudo-element
   would sit too close to the icon. Pull it 4px to the left. */
:root[data-sidebar="collapsed"] .nav-item.active::before { left: -3px; }

.sidebar {
  position: fixed;
  top: 0;
  left: 0;
  width: 240px;
  height: 100vh;
  z-index: 30;
  transform: none;
  background: var(--sidebar-bg);
  border-right: 1px solid var(--panel-edge);
  display: flex;
  flex-direction: column;
  transition: width 0.18s ease;
}
:root[data-sidebar="collapsed"] .sidebar { width: 56px; }

/* ============================================================
   Unified chrome offsets + persistent market bar.
   The sidebar + market bar are fixed; page content is pushed clear via
   body padding. All keyed on <html data-chrome="on"> so non-chrome pages
   (login/auth) are never affected. --marketbar-h is the bar's height.
   ============================================================ */
:root { --marketbar-h: 30px; }

:root[data-chrome="on"] body {
  padding-left: 240px;
  padding-bottom: var(--marketbar-h);
  transition: padding-left 0.18s ease;
}
:root[data-chrome="on"][data-sidebar="collapsed"] body { padding-left: 56px; }
/* Market bar pinned to the top instead of the bottom. */
:root[data-chrome="on"][data-marketbar="top"] body {
  padding-bottom: 0;
  padding-top: var(--marketbar-h);
}
/* Hidden via drawer → reclaim the bar's reserved space. */
:root[data-chrome="on"][data-marketbar-hidden="1"] body {
  padding-top: 0;
  padding-bottom: 0;
}

.market-bar {
  position: fixed;
  left: 240px;
  right: 0;
  bottom: 0;
  height: var(--marketbar-h);
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
  padding: 0 18px;
  box-sizing: border-box;
  background: var(--sidebar-bg);
  border-top: 1px solid var(--panel-edge);
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 10.5px;
  color: var(--muted-dim);
  transition: transform 0.2s ease, left 0.18s ease;
}
:root[data-sidebar="collapsed"] .market-bar { left: 56px; }
:root[data-marketbar="top"] .market-bar {
  bottom: auto;
  top: 0;
  border-top: 0;
  border-bottom: 1px solid var(--panel-edge);
}
:root[data-marketbar-hidden="1"] .market-bar { transform: translateY(100%); }
:root[data-marketbar="top"][data-marketbar-hidden="1"] .market-bar { transform: translateY(-100%); }
.market-bar-grp { display: flex; gap: 16px; flex-wrap: wrap; align-items: center; }
.market-bar b { color: var(--text); font-weight: 500; }

/* Drawer handle — fixed (sibling of the bar) so it stays put when the bar
   slides away. Rides the bar's outer edge when shown; drops to the screen
   edge when hidden. Chevron points the direction the bar will travel. */
.market-bar-toggle {
  position: fixed;
  right: 16px;
  bottom: var(--marketbar-h);
  z-index: 41;
  width: 34px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--panel-edge);
  border-bottom: 0;
  border-radius: 6px 6px 0 0;
  background: var(--sidebar-bg);
  color: var(--muted);
  cursor: pointer;
  transition: bottom 0.2s ease, top 0.2s ease;
}
.market-bar-toggle:hover { color: var(--cream); }
.market-bar-toggle svg { width: 14px; height: 14px; transition: transform 0.2s ease; }
:root[data-marketbar-hidden="1"] .market-bar-toggle { bottom: 0; }
:root[data-marketbar="top"] .market-bar-toggle {
  bottom: auto;
  top: var(--marketbar-h);
  border-bottom: 1px solid var(--panel-edge);
  border-top: 0;
  border-radius: 0 0 6px 6px;
}
:root[data-marketbar="top"][data-marketbar-hidden="1"] .market-bar-toggle { top: 0; }
/* Chevron orientation. Base svg is ▼ (points down).
   bottom + shown    → ▼ (hide downward)
   bottom + hidden   → ▲ (show upward)
   top    + shown    → ▲ (hide upward)
   top    + hidden   → ▼ (show downward) */
:root[data-marketbar="bottom"][data-marketbar-hidden="1"] .market-bar-toggle svg { transform: rotate(180deg); }
:root[data-marketbar="top"] .market-bar-toggle svg { transform: rotate(180deg); }
:root[data-marketbar="top"][data-marketbar-hidden="1"] .market-bar-toggle svg { transform: rotate(0deg); }
.sidebar-inner {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 14px 10px 10px;
  min-height: 0;
}

/* Brand block — logo + wordmark + optional search affordance. */
.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 8px 14px;
  border-bottom: 1px solid var(--panel-edge-2);
  margin-bottom: 10px;
}
.sidebar-brand .brand-link {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  flex: 1;
  min-width: 0;
  text-decoration: none;
  color: inherit;
}
.sidebar-brand .brand-mark {
  width: 22px;
  height: 22px;
  filter: none;
}
.brand-wordmark {
  font-family: var(--sans);
  /* 500 (Kräftig) — same weight as the landing wordmark so the brand
     reads consistently across pages. The +1px size bump keeps the
     wordmark visually distinct from the 13.5px nav-item labels below. */
  font-weight: 500;
  font-size: 15px;
  letter-spacing: 0.01em;
  color: var(--cream);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sidebar-search {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 6px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}
.sidebar-search:hover {
  color: var(--cream);
  background: var(--panel-edge-2);
  border-color: var(--panel-edge);
}

/* Nav list. Items use icon + label + optional meta cell. */
.sidebar-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--panel-edge) transparent;
}
.sidebar-nav::-webkit-scrollbar { width: 6px; }
.sidebar-nav::-webkit-scrollbar-thumb {
  background: var(--panel-edge);
  border-radius: 3px;
}
.nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 12px;
  border-radius: 7px;
  color: var(--muted);
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 500;
  /* Pin line-height so the nav-row height is identical on every page.
     Without it the label inherits `line-height: normal`, which resolves to
     different pixel heights depending on the host page's base font — that
     was the row-spacing drift between new-design and legacy pages. 1.15 is
     tighter than any page's default, so rows are smaller everywhere too. */
  line-height: 1.15;
  letter-spacing: 0.005em;
  text-decoration: none;
  outline: none;
  transition: color 0.15s ease, background-color 0.15s ease;
}
.nav-item:hover {
  color: var(--cream);
  background: var(--panel-edge-2);
}
.nav-item:focus-visible {
  box-shadow: 0 0 0 2px var(--gold-soft);
}
.nav-item.active {
  color: var(--cream);
  background: var(--gold-soft);
}

/* Nested sub-nav item (PR-7 2026-05-22). Indented under its parent;
   shrinks icon + label slightly so /saved reads as a child of
   /newsletters. */
.nav-item.nav-sub {
  padding-left: 30px;
  font-size: 12.5px;
  color: var(--muted);
}
.nav-item.nav-sub .nav-icon {
  width: 14px;
  height: 14px;
}
:root[data-sidebar="collapsed"] .nav-item.nav-sub {
  padding-left: 0;
}
/* Sub-nav active state — restate color so `.nav-item.nav-sub`'s color
 * (declared later in source order at equal specificity) doesn't override
 * `.nav-item.active`'s cream. Fixes /social/lunarcrush highlighting the
 * 'Lunar Crush' child item correctly. */
.nav-item.nav-sub.active {
  color: var(--cream);
}
.nav-item.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 7px;
  bottom: 7px;
  width: 2px;
  background: var(--gold);
  border-radius: 0 2px 2px 0;
}
.nav-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: inherit;
}
.nav-label {
  flex: 1;
  min-width: 0;
  line-height: 1.15;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Meta cells next to nav items. Variants:
     .count           — numeric badge (neutral)
     .count.is-gold   — numeric badge highlighted gold
     .dot             — single status dot (+ is-warn/pos/neg)
     .spark           — inline 36×14 sparkline (+ is-neg flips color)
   Rendered from a data object — see dashboard.html script. */
.nav-meta {
  margin-left: auto;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
}
/* Respect the `hidden` attribute. The markup ships these badges hidden and
   JS unhides them only when there's a real count; without this the
   `display: inline-flex` above out-specifies the UA [hidden] rule, so an
   empty badge renders as a stray gold chip next to Watchlists/Newsletters. */
.nav-meta[hidden] { display: none !important; }
.nav-meta.count {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  color: var(--cream);
  background: var(--panel-edge-2);
  padding: 2px 7px;
  border-radius: 5px;
  letter-spacing: 0.02em;
}
.nav-meta.count.is-gold {
  color: var(--gold-bright);
  background: var(--gold-soft);
}
.nav-meta.dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--muted);
}
.nav-meta.dot.is-warn { background: var(--warn); }
.nav-meta.dot.is-pos  { background: var(--pos); }
.nav-meta.dot.is-neg  { background: var(--neg); }
.nav-meta.spark {
  width: 36px;
  height: 14px;
  color: var(--pos);
}
.nav-meta.spark.is-neg { color: var(--neg); }

/* Sidebar footer — account block + theme toggle + logout. */
.sidebar-footer {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--panel-edge-2);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.account-block {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 4px 6px;
  border-radius: 7px;
  color: inherit;
  text-decoration: none;
  transition: background-color 0.15s ease;
}
.account-block:hover {
  background: var(--panel-edge-2);
}
.account-block.active {
  background: var(--gold-soft);
}
.account-avatar {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--gold-soft);
  border: 1px solid var(--gold-soft);
  color: var(--gold-bright);
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.account-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  line-height: 1.2;
}
.account-name {
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--cream);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.account-email {
  font-family: var(--sans);
  font-size: 11px;
  color: var(--muted-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sidebar-footer-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 2px;
}
/* Sidebar variants of the theme toggle + logout button — smaller
   than the auth-page topbar versions and fitted to the footer. */
.sidebar-footer-actions .theme-toggle {
  width: 30px;
  height: 30px;
  border-radius: 7px;
}
.sidebar-footer-actions .theme-toggle svg { width: 15px; height: 15px; }
.sidebar-footer-actions .logout-form { flex: 1; margin: 0; }
.sidebar-footer-actions .logout-btn {
  width: 100%;
  padding: 6px 10px;
  font-size: 12.5px;
  font-weight: 500;
}

/* Mobile drawer trigger + scrim. Hidden on desktop. */
.nav-toggle {
  display: none;
  position: fixed;
  top: 14px;
  left: 14px;
  z-index: 110;
  width: 38px;
  height: 38px;
  border-radius: 8px;
  border: 1px solid var(--panel-edge);
  background: var(--sidebar-bg);
  color: var(--cream);
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.nav-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 99;
}

@media (max-width: 760px) {
  /* Shared mobile drawer behaviour for every in-app page. The fixed
     desktop rail becomes an off-canvas drawer; body offset collapses to 0
     so content spans full width. */
  :root[data-chrome="on"] body { padding-left: 0; }
  .nav-toggle { display: inline-flex; }
  body[data-page="dashboard"] .dashboard-main { padding: 70px 18px 80px; }
  body[data-page="account"]   .account-main   { padding: 70px 18px 80px; }
  body[data-page="watchlists"] .account-main  { padding: 70px 18px 80px; }

  .sidebar,
  :root[data-sidebar="collapsed"] .sidebar {
    top: 0;
    left: 0;
    bottom: 0;
    width: 280px;
    transform: translateX(-100%);
    transition: transform 0.22s ease;
    z-index: 100;
  }
  body[data-nav-open="true"] .sidebar { transform: translateX(0); }
  body[data-nav-open="true"] .nav-backdrop { display: block; }

  /* Market bar spans full width on mobile (no rail to clear). */
  .market-bar { left: 0; }
}

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width: 980px) {
  body[data-page="login"] main {
    grid-template-columns: 1fr;
    gap: 48px;
    padding: 24px 28px 56px;
  }
  body[data-page="login"] .card {
    justify-self: center;
    margin-right: 0;
  }
  .wordmark { font-size: 56px; }
  .hero-logo { width: 220px; }
  .topbar { padding: 18px 28px 0; }
}

@media (max-width: 520px) {
  .wordmark { font-size: 44px; }
  .tagline { font-size: 12px; letter-spacing: 0.16em; }
  .tagline::before, .tagline::after { width: 22px; }
  .card { padding: 32px 26px; }
  .card h2, .card h1 { font-size: 30px; }
  .topbar { padding: 16px 18px 0; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; }
}
