detached c19dc5b

refactor(homepage): redesign layout and styling

- Restructure component layout for improved visual hierarchy
- Update color scheme to use dynamic CSS custom properties
- Refine spacing and typography throughout
- Enhance responsive design breakpoints
- Improve section organization and content flow
- Apply terminal-style aesthetic consistent with omnibox theme
- Update shortcuts display and interaction patterns
commit
c19dc5b178a643c84b06dad8b477d37dfe5a7ff2
author
bamen · · 2025-10-06 20:15 UTC
committer
bamen · · 2025-10-06 18:38 UTC
parent
70a4bbc
signature
unsigned
1 file · +586 -390
M gui/src/pages/Homepage.svelte +586 -390
@@ -482,6 +482,39 @@
482482
483483 let quickAccess = $derived<HistoryItem[]>((pinnedSites.size, buildQuickAccess()));
484484 let quickAccessLoading = $derived(topVisitedLoading || historyLoading);
485+ interface LatestVisitMeta {
486+ entry: HistoryItem;
487+ relative: string;
488+ absolute: string;
489+ domain: string;
490+ title: string;
491+ }
492+
493+ const latestVisitInfo = $derived<LatestVisitMeta | null>((() => {
494+ if (!historyItems.length) return null;
495+
496+ let latest: HistoryItem | null = null;
497+ let latestEpoch = Number.NEGATIVE_INFINITY;
498+
499+ for (const entry of historyItems) {
500+ const epoch = Number(new Date(entry.last_visited));
501+ if (!Number.isFinite(epoch)) continue;
502+ if (epoch > latestEpoch) {
503+ latest = entry;
504+ latestEpoch = epoch;
505+ }
506+ }
507+
508+ if (!latest) return null;
509+
510+ return {
511+ entry: latest,
512+ relative: formatTime(latest.last_visited),
513+ absolute: formatCalendarDate(latest.last_visited),
514+ domain: getDomain(latest.url),
515+ title: getDisplayTitle(latest)
516+ };
517+ })());
485518
486519 const persistTheme = (mode: ThemeMode) => {
487520 try {
@@ -613,6 +646,28 @@
613646 return () => observer.disconnect();
614647 };
615648
649+ // Helper to check if text overflows and apply truncation class
650+ const checkOverflow = (node: HTMLElement) => {
651+ const check = () => {
652+ if (node.scrollWidth > node.clientWidth) {
653+ node.classList.add('truncated');
654+ } else {
655+ node.classList.remove('truncated');
656+ }
657+ };
658+
659+ check();
660+
661+ const resizeObserver = new ResizeObserver(check);
662+ resizeObserver.observe(node);
663+
664+ return {
665+ destroy() {
666+ resizeObserver.disconnect();
667+ }
668+ };
669+ };
670+
616671 onMount(() => {
617672 loadPinnedSites();
618673 initializeShortcuts();
@@ -651,8 +706,16 @@
651706 </svelte:head>
652707
653708 <div class="homepage-shell">
654- <div class="homepage-content">
655- <div class="top-bar">
709+ <div class="terminal-frame">
710+ <header class="terminal-header">
711+ <div class="terminal-heading">
712+ <span class="terminal-path">dumb://home</span>
713+ <span class="terminal-meta">
714+ {statsLoading ? 'syncing…' : `${stats?.recent_count ?? 0} recent`}
715+ · {historyItems.length} entries
716+ · {pinnedSites.size} pinned
717+ </span>
718+ </div>
656719 <button
657720 class="theme-toggle-button"
658721 type="button"
@@ -667,7 +730,9 @@
667730 <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
668731 <path
669732 fill="currentColor"
670- d="M21 12.79A9 9 0 0111.21 3 7 7 0 0012 17a7 7 0 009-4.21z"
733+ fill-rule="evenodd"
734+ clip-rule="evenodd"
735+ d="M17.293 13.293A8 8 0 0 1 10.707 2.997a8.001 8.001 0 1 0 6.586 10.296z"
671736 />
672737 </svg>
673738 {:else}
@@ -686,9 +751,57 @@
686751 </svg>
687752 {/if}
688753 </button>
689- </div>
690- <div class="main-panels">
691- <section class="history-panel brutal-panel">
754+ </header>
755+
756+ <div class="terminal-body">
757+ <div class="terminal-status-row">
758+ <div class="status-chip">
759+ <span class="chip-label">history</span>
760+ <span class="chip-value">{historyItems.length}</span>
761+ </div>
762+ <div class="status-chip">
763+ <span class="chip-label">pinned</span>
764+ <span class="chip-value">{pinnedSites.size}</span>
765+ </div>
766+ <div class="status-chip">
767+ <span class="chip-label">quick-links</span>
768+ <span class="chip-value">{quickAccess.length}</span>
769+ </div>
770+ {#if stats && stats.total_entries}
771+ <div class="status-chip">
772+ <span class="chip-label">stored</span>
773+ <span class="chip-value">{stats.total_entries}</span>
774+ </div>
775+ {/if}
776+ </div>
777+
778+ <div
779+ class="last-visit-banner"
780+ role="button"
781+ tabindex={latestVisitInfo ? 0 : -1}
782+ onclick={() => latestVisitInfo && navigateTo(latestVisitInfo.entry.url)}
783+ onkeydown={(event) => {
784+ if (event.key === 'Enter' && latestVisitInfo) {
785+ navigateTo(latestVisitInfo.entry.url);
786+ }
787+ }}
788+ aria-label={latestVisitInfo ? `Open ${latestVisitInfo.title}` : 'No recorded visits'}
789+ >
790+ <span class="banner-label">last-visit</span>
791+ {#if latestVisitInfo}
792+ <span class="banner-title" use:checkOverflow>
793+ {latestVisitInfo.title}
794+ </span>
795+ <span class="banner-domain">{latestVisitInfo.domain}</span>
796+ <span class="banner-time">{latestVisitInfo.relative}</span>
797+ <span class="banner-absolute">{latestVisitInfo.absolute}</span>
798+ {:else}
799+ <span class="banner-empty">none recorded yet</span>
800+ {/if}
801+ </div>
802+
803+ <div class="terminal-grid main-panels">
804+ <section class="history-panel terminal-pane">
692805 <div class="panel-header">
693806 <h2 class="panel-title">Recent History</h2>
694807 <p class="panel-subtitle">Scroll to revisit anything from your latest sessions.</p>
@@ -751,10 +864,14 @@
751864 </div>
752865 <div class="history-item-content">
753866 <div class="history-item-main">
754- <div class="history-title">{getDisplayTitle(item)}</div>
867+ <div class="history-title" use:checkOverflow>
868+ {getDisplayTitle(item)}
869+ </div>
755870 <div class="history-time">{formatTime(item.last_visited)}</div>
756871 </div>
757- <div class="history-url">{@html highlightDomainInUrl(item.url)}</div>
872+ <div class="history-url" use:checkOverflow>
873+ {@html highlightDomainInUrl(item.url)}
874+ </div>
758875 </div>
759876 <div class="history-actions">
760877 <div
@@ -770,7 +887,7 @@
770887 <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
771888 </svg>
772889 {:else}
773- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">
890+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round" stroke-linecap="round" aria-hidden="true">
774891 <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
775892 </svg>
776893 {/if}
@@ -808,7 +925,7 @@
808925 </div>
809926 </section>
810927
811- <section class="quick-access-panel brutal-panel">
928+ <section class="quick-access-panel terminal-pane">
812929 <div class="panel-header">
813930 <h2 class="panel-title">Jump back in</h2>
814931 <p class="panel-subtitle">Direct access to the sites you like the most.</p>
@@ -869,7 +986,9 @@
869986 {/if}
870987 </div>
871988 <div class="quick-access-meta-compact">
872- <div class="quick-access-title-compact">{getDisplayTitle(item)}</div>
989+ <div class="quick-access-title-compact" use:checkOverflow>
990+ {getDisplayTitle(item)}
991+ </div>
873992 <div class="quick-access-domain-compact">{getDomain(item.url)}</div>
874993 </div>
875994 <div class="quick-access-actions-compact">
@@ -886,7 +1005,7 @@
8861005 <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
8871006 </svg>
8881007 {:else}
889- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">
1008+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round" stroke-linecap="round" aria-hidden="true">
8901009 <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
8911010 </svg>
8921011 {/if}
@@ -899,132 +1018,165 @@
8991018 {/if}
9001019 </div>
9011020 </section>
902- </div>
903-
904- <section class="shortcuts-panel brutal-panel">
905- <div class="panel-header">
906- <h2 class="panel-title">Keyboard Shortcuts</h2>
907- <p class="panel-subtitle">Stay quick with the essentials.</p>
908- </div>
909- <div class="panel-body">
910- {#if shortcutsLoading}
911- <div class="loading">Loading shortcuts...</div>
912- {:else}
913- <div class="shortcuts-list">
914- {#each shortcuts as shortcut (shortcut.key)}
915- <div class="shortcut-item">
916- <div class="shortcut-key-badge">{shortcut.key}</div>
917- <div class="shortcut-desc">{shortcut.description}</div>
918- </div>
919- {/each}
920- </div>
921- {/if}
9221021 </div>
923- </section>
9241022
925-
926- <section class="stats-panel brutal-panel">
927- <div class="panel-header">
928- <h2 class="panel-title">Usage Stats</h2>
929- <p class="panel-subtitle">Your browsing activity at a glance.</p>
930- </div>
931- <div class="panel-body">
932- {#if statsLoading}
933- <div class="loading">Loading stats...</div>
934- {:else if stats}
935- <div class="stats-grid-horizontal">
936- <div class="stat-item-horizontal">
937- <div class="stat-value">{stats.total_entries}</div>
938- <div class="stat-label">Entries Stored</div>
939- </div>
940- <div class="stat-item-horizontal">
941- <div class="stat-value">{stats.recent_count}</div>
942- <div class="stat-label">Recent Window</div>
943- </div>
944- {#if stats.newest_entry}
945- <div class="stat-item-horizontal">
946- <div class="stat-value">{formatTime(stats.newest_entry)}</div>
947- <div class="stat-label">Newest Visit</div>
1023+ <div class="terminal-grid supporting-panels">
1024+ <section class="stats-panel terminal-pane">
1025+ <div class="panel-header">
1026+ <h2 class="panel-title">Usage Stats</h2>
1027+ <p class="panel-subtitle">Your browsing activity at a glance.</p>
1028+ </div>
1029+ <div class="panel-body">
1030+ {#if statsLoading}
1031+ <div class="loading">Loading stats...</div>
1032+ {:else if stats}
1033+ <div class="stats-grid-horizontal">
1034+ <div class="stat-item-horizontal">
1035+ <div class="stat-value">{stats.total_entries}</div>
1036+ <div class="stat-label">Entries Stored</div>
1037+ </div>
1038+ <div class="stat-item-horizontal">
1039+ <div class="stat-value">{stats.recent_count}</div>
1040+ <div class="stat-label">Recent Window</div>
1041+ </div>
1042+ {#if stats.newest_entry}
1043+ <div class="stat-item-horizontal">
1044+ <div class="stat-value">{formatTime(stats.newest_entry)}</div>
1045+ <div class="stat-label">Newest Visit</div>
1046+ </div>
1047+ {/if}
1048+ {#if stats.oldest_entry}
1049+ <div class="stat-item-horizontal">
1050+ <div class="stat-value">{formatCalendarDate(stats.oldest_entry)}</div>
1051+ <div class="stat-label">Oldest Entry</div>
1052+ </div>
1053+ {/if}
9481054 </div>
949- {/if}
950- {#if stats.oldest_entry}
951- <div class="stat-item-horizontal">
952- <div class="stat-value">{formatCalendarDate(stats.oldest_entry)}</div>
953- <div class="stat-label">Oldest Entry</div>
1055+ {:else}
1056+ <div class="empty-state compact">
1057+ <p>No statistics available</p>
9541058 </div>
9551059 {/if}
9561060 </div>
957- {:else}
958- <div class="empty-state compact">
959- <p>No statistics available</p>
1061+ </section>
1062+
1063+ <section class="shortcuts-panel terminal-pane">
1064+ <div class="panel-header">
1065+ <h2 class="panel-title">Keyboard Shortcuts</h2>
1066+ <p class="panel-subtitle">Stay quick with the essentials.</p>
9601067 </div>
961- {/if}
1068+ <div class="panel-body">
1069+ {#if shortcutsLoading}
1070+ <div class="loading">Loading shortcuts...</div>
1071+ {:else}
1072+ <div class="shortcuts-list">
1073+ {#each shortcuts as shortcut (shortcut.key)}
1074+ <div class="shortcut-item">
1075+ <div class="shortcut-key-badge">{shortcut.key}</div>
1076+ <div class="shortcut-desc">{shortcut.description}</div>
1077+ </div>
1078+ {/each}
1079+ </div>
1080+ {/if}
1081+ </div>
1082+ </section>
9621083 </div>
963- </section>
964-
1084+ </div>
9651085 </div>
9661086
9671087 <Footer />
9681088 </div>
9691089
9701090 <style>
971-/* Homepage Layout Styles */
9721091 .homepage-shell {
9731092 min-height: 100vh;
9741093 background-color: var(--dynamic-bg);
9751094 color: var(--dynamic-text);
9761095 display: flex;
9771096 flex-direction: column;
978- padding: clamp(1.75rem, 3vw, 3rem);
979- font-family: "Fira Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
1097+ padding: clamp(1.5rem, 4vw, 2.5rem);
1098+ font-family:
1099+ "JetBrains Mono",
1100+ "Fira Code",
1101+ "SFMono-Regular",
1102+ Menlo,
1103+ monospace;
1104+ line-height: 1.45;
9801105 }
9811106
9821107 .homepage-shell * {
9831108 box-sizing: border-box;
9841109 }
9851110
986-.homepage-content {
1111+.terminal-frame {
9871112 flex: 1;
9881113 width: 100%;
989- max-width: 1180px;
1114+ max-width: 1160px;
9901115 margin: 0 auto;
9911116 display: flex;
9921117 flex-direction: column;
993- gap: clamp(1.75rem, 2.6vw, 2.75rem);
1118+ border: 1px solid var(--dynamic-border);
1119+ background: color-mix(in srgb, var(--dynamic-surface) 80%, var(--dynamic-bg) 20%);
1120+ box-shadow:
1121+ inset 0 0 0 1px color-mix(in srgb, var(--dynamic-border) 30%, transparent),
1122+ 0 16px 28px -24px rgb(0 0 0 / 0.6);
1123+}
1124+
1125+.terminal-header {
1126+ display: flex;
1127+ align-items: center;
1128+ justify-content: space-between;
1129+ gap: 1rem;
1130+ padding: 0.85rem 1.1rem;
1131+ border-bottom: 1px solid var(--dynamic-border);
1132+ background: color-mix(in srgb, var(--dynamic-bg) 92%, var(--dynamic-surface) 8%);
1133+ text-transform: uppercase;
1134+ letter-spacing: 0.08em;
1135+ font-size: 0.78rem;
9941136 }
9951137
996-.top-bar {
1138+.terminal-heading {
9971139 display: flex;
998- justify-content: flex-end;
1140+ flex-direction: column;
1141+ gap: 0.35rem;
1142+}
1143+
1144+.terminal-path {
1145+ font-weight: 600;
1146+ color: var(--dynamic-text);
1147+}
1148+
1149+.terminal-meta {
1150+ color: var(--dynamic-muted);
1151+ font-size: 0.72rem;
1152+ letter-spacing: 0.12em;
9991153 }
10001154
10011155 .theme-toggle-button {
1002- width: 3rem;
1003- height: 3rem;
1156+ width: 2.5rem;
1157+ height: 2.5rem;
10041158 display: inline-flex;
10051159 align-items: center;
10061160 justify-content: center;
1007- border: 2px solid var(--dynamic-border);
1161+ border: 1px solid var(--dynamic-border);
1162+ background-color: var(--dynamic-bg);
1163+ color: var(--dynamic-muted);
1164+ transition: color 150ms ease, border-color 150ms ease, background-color 150ms ease;
10081165 border-radius: 0;
1009- background-color: var(--dynamic-surface);
1010- color: var(--dynamic-text);
1011- transition:
1012- background-color 200ms ease,
1013- color 200ms ease,
1014- border-color 200ms ease;
10151166 cursor: pointer;
10161167 }
10171168
10181169 .theme-toggle-button:hover,
10191170 .theme-toggle-button:focus-visible {
1020- border-color: var(--dynamic-accent);
1021- color: var(--dynamic-accent);
1171+ border-color: color-mix(in srgb, var(--dynamic-border) 45%, var(--dynamic-text) 55%);
1172+ color: var(--dynamic-text);
1173+ background-color: color-mix(in srgb, var(--dynamic-bg) 80%, var(--dynamic-surface) 20%);
10221174 outline: none;
10231175 }
10241176
10251177 .theme-toggle-button svg {
1026- width: 1.5rem;
1027- height: 1.5rem;
1178+ width: 1.3rem;
1179+ height: 1.3rem;
10281180 }
10291181
10301182 .sr-only {
@@ -1039,99 +1191,158 @@
10391191 border: 0;
10401192 }
10411193
1042-.brutal-panel {
1043- border: 2px solid var(--dynamic-border);
1044- background-color: var(--dynamic-surface);
1045- border-radius: 0;
1194+.terminal-body {
10461195 display: flex;
10471196 flex-direction: column;
1048- gap: 0;
1197+ gap: 1.25rem;
1198+ padding: 1.25rem 1.5rem 1.5rem;
1199+ background: var(--dynamic-bg);
10491200 }
10501201
1202+.terminal-status-row {
1203+ display: flex;
1204+ flex-wrap: wrap;
1205+ gap: 0.75rem;
1206+}
10511207
1052-
1053-.loading {
1054- padding: 1.25rem;
1055- text-align: center;
1208+.status-chip {
1209+ display: inline-flex;
1210+ align-items: center;
1211+ gap: 0.5rem;
1212+ padding: 0.45rem 0.8rem;
1213+ border: 1px solid var(--dynamic-border);
1214+ background: color-mix(in srgb, var(--dynamic-bg) 92%, var(--dynamic-surface) 8%);
1215+ font-size: 0.68rem;
1216+ letter-spacing: 0.1em;
1217+ text-transform: uppercase;
10561218 color: var(--dynamic-muted);
1057- border: 2px dashed var(--dynamic-border);
1058- background-color: var(--dynamic-bg);
10591219 }
10601220
1061-.empty-state {
1062- border: 2px dashed var(--dynamic-border);
1063- padding: 1.75rem;
1064- display: flex;
1065- flex-direction: column;
1066- gap: 0.5rem;
1067- text-align: center;
1221+.status-chip .chip-value {
1222+ color: var(--dynamic-text);
1223+ font-weight: 600;
1224+}
1225+
1226+.last-visit-banner {
1227+ margin-top: 0.9rem;
1228+ display: grid;
1229+ grid-template-columns: minmax(0, auto) minmax(0, 1fr) minmax(120px, auto) minmax(120px, auto) minmax(120px, auto);
1230+ gap: 0.75rem;
10681231 align-items: center;
1232+ padding: 0.75rem 1rem;
1233+ border: 1px solid var(--dynamic-border);
1234+ background: color-mix(in srgb, var(--dynamic-bg) 90%, var(--dynamic-surface) 10%);
1235+ color: var(--dynamic-text);
1236+ text-transform: uppercase;
1237+ letter-spacing: 0.08em;
1238+ transition: background-color 150ms ease, border-color 150ms ease;
1239+ cursor: pointer;
1240+}
1241+
1242+.last-visit-banner:hover,
1243+.last-visit-banner:focus-visible {
1244+ background: color-mix(in srgb, var(--dynamic-bg) 72%, var(--dynamic-surface) 28%);
1245+ border-color: color-mix(in srgb, var(--dynamic-border) 45%, var(--dynamic-text) 55%);
1246+ outline: none;
1247+}
1248+
1249+.last-visit-banner[tabindex="-1"],
1250+.last-visit-banner[tabindex="-1"]:hover {
1251+ cursor: default;
1252+ background: color-mix(in srgb, var(--dynamic-bg) 95%, var(--dynamic-surface) 5%);
1253+}
1254+
1255+.banner-label {
10691256 color: var(--dynamic-muted);
1070- background-color: var(--dynamic-bg);
1257+ font-size: 0.68rem;
10711258 }
10721259
1073-.empty-state h3 {
1074- margin: 0;
1260+.banner-title {
1261+ font-weight: 600;
1262+ white-space: nowrap;
1263+ overflow: hidden;
1264+ letter-spacing: 0.06em;
1265+}
1266+
1267+:global(.banner-title.truncated) {
1268+ mask-image: linear-gradient(to right, black 85%, transparent 100%);
1269+ -webkit-mask-image: linear-gradient(to right, black 85%, transparent 100%);
1270+}
1271+
1272+.banner-domain {
1273+ color: var(--dynamic-muted);
1274+ font-size: 0.68rem;
1275+ letter-spacing: 0.1em;
1276+}
1277+
1278+.banner-time {
1279+ font-size: 0.72rem;
10751280 color: var(--dynamic-text);
1076- font-size: 1.1rem;
1281+ white-space: nowrap;
10771282 }
10781283
1079-.empty-state p {
1080- margin: 0;
1284+.banner-absolute {
1285+ font-size: 0.68rem;
10811286 color: var(--dynamic-muted);
1287+ white-space: nowrap;
10821288 }
10831289
1084-.empty-state.compact {
1085- padding: 1.25rem;
1290+.banner-empty {
1291+ grid-column: 2 / -1;
1292+ color: var(--dynamic-muted);
1293+ font-size: 0.72rem;
1294+ letter-spacing: 0.1em;
1295+}
1296+
1297+.terminal-grid {
1298+ display: grid;
1299+ gap: 1rem;
10861300 }
10871301
1088-/* Main panels with height matching */
10891302 .main-panels {
1090- display: flex;
1091- flex-wrap: wrap;
1092- gap: clamp(1.5rem, 2vw, 2rem);
1093- align-items: flex-start;
1303+ grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
10941304 }
10951305
1096-.history-panel {
1097- flex: 1 1 55%;
1098- min-width: min(32rem, 100%);
1099- display: flex;
1100- flex-direction: column;
1101- min-height: 0;
1306+.supporting-panels {
1307+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
11021308 }
11031309
1104-.quick-access-panel {
1105- flex: 1 1 35%;
1106- min-width: min(24rem, 100%);
1310+.terminal-pane {
1311+ border: 1px solid var(--dynamic-border);
1312+ background: color-mix(in srgb, var(--dynamic-bg) 88%, var(--dynamic-surface) 12%);
11071313 display: flex;
11081314 flex-direction: column;
11091315 min-height: 0;
1316+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dynamic-border) 18%, transparent);
11101317 }
11111318
11121319 .panel-header {
11131320 display: flex;
11141321 flex-direction: column;
1115- gap: 0.4rem;
1116- padding: clamp(1.25rem, 2vw, 1.75rem) clamp(1.5rem, 2.5vw, 2rem);
1117- border-bottom: 2px solid var(--dynamic-border);
1118- background-color: var(--dynamic-surface);
1322+ gap: 0.3rem;
1323+ padding: 1rem 1.1rem;
1324+ border-bottom: 1px solid var(--dynamic-border);
1325+ background: color-mix(in srgb, var(--dynamic-bg) 75%, transparent);
11191326 }
11201327
11211328 .panel-title {
11221329 margin: 0;
1123- font-size: 1.3rem;
1124- font-weight: 600;
1330+ font-size: 0.95rem;
1331+ text-transform: uppercase;
1332+ letter-spacing: 0.08em;
1333+ color: var(--dynamic-text);
11251334 }
11261335
11271336 .panel-subtitle {
11281337 margin: 0;
1129- font-size: 0.95rem;
1338+ font-size: 0.72rem;
11301339 color: var(--dynamic-muted);
1340+ letter-spacing: 0.1em;
1341+ text-transform: uppercase;
11311342 }
11321343
11331344 .panel-body {
1134- padding: clamp(1.25rem, 2vw, 1.75rem) clamp(1.5rem, 2.5vw, 2rem);
1345+ padding: 1.1rem 1.1rem 1.25rem;
11351346 display: flex;
11361347 flex-direction: column;
11371348 gap: 1.1rem;
@@ -1139,8 +1350,48 @@
11391350 overflow: hidden;
11401351 }
11411352
1353+.loading {
1354+ padding: 0.9rem;
1355+ text-align: center;
1356+ color: var(--dynamic-muted);
1357+ border: 1px dashed var(--dynamic-border);
1358+ background-color: color-mix(in srgb, var(--dynamic-bg) 85%, var(--dynamic-surface) 15%);
1359+ text-transform: uppercase;
1360+ letter-spacing: 0.08em;
1361+ font-size: 0.7rem;
1362+}
1363+
1364+.empty-state {
1365+ border: 1px dashed var(--dynamic-border);
1366+ padding: 1.4rem;
1367+ display: flex;
1368+ flex-direction: column;
1369+ gap: 0.5rem;
1370+ align-items: center;
1371+ text-align: center;
1372+ color: var(--dynamic-muted);
1373+ background-color: color-mix(in srgb, var(--dynamic-bg) 90%, var(--dynamic-surface) 10%);
1374+ letter-spacing: 0.06em;
1375+}
1376+
1377+.empty-state h3 {
1378+ margin: 0;
1379+ color: var(--dynamic-text);
1380+ font-size: 0.9rem;
1381+ text-transform: uppercase;
1382+}
1383+
1384+.empty-state p {
1385+ margin: 0;
1386+ font-size: 0.72rem;
1387+}
1388+
1389+.empty-state.compact {
1390+ padding: 1rem;
1391+}
1392+
11421393 .history-body {
1143- gap: 1rem;
1394+ gap: 0.75rem;
11441395 display: flex;
11451396 flex-direction: column;
11461397 min-height: 0;
@@ -1150,26 +1401,21 @@
11501401 .history-list {
11511402 display: flex;
11521403 flex-direction: column;
1153- gap: 0.85rem;
11541404 flex: 1;
11551405 min-height: 0;
11561406 overflow-y: auto;
1157- background-color: var(--dynamic-surface-variant);
1158- border: 2px solid var(--dynamic-border);
1159- padding: 0.5rem;
1407+ border: 1px solid var(--dynamic-border);
1408+ background: color-mix(in srgb, var(--dynamic-bg) 95%, var(--dynamic-surface) 5%);
11601409 }
11611410
11621411 .history-item {
1163- display: flex;
1164- align-items: flex-start;
1412+ display: grid;
1413+ grid-template-columns: auto 1fr auto;
1414+ align-items: center;
11651415 gap: 0.75rem;
1166- border-bottom: 1px solid var(--dynamic-border);
1167- background-color: var(--dynamic-surface-variant);
1168- padding: 0.75rem 0.5rem;
1169- cursor: pointer;
1170- transition:
1171- background-color 200ms ease,
1172- border-color 200ms ease;
1416+ padding: 0.6rem 0.9rem;
1417+ border-bottom: 1px dashed var(--dynamic-border);
1418+ transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease;
11731419 }
11741420
11751421 .history-item:last-child {
@@ -1178,26 +1424,25 @@
11781424
11791425 .history-item:hover,
11801426 .history-item:focus-visible {
1181- background-color: var(--dynamic-surface);
1427+ background: color-mix(in srgb, var(--dynamic-bg) 65%, var(--dynamic-surface) 35%);
11821428 outline: none;
11831429 }
11841430
11851431 .history-item.deleting {
1186- opacity: 0.4;
1432+ opacity: 0.35;
11871433 pointer-events: none;
1188- transform: translateX(6px);
1434+ transform: translateX(4px);
11891435 }
11901436
11911437 .history-item-leading {
1192- width: 44px;
1193- height: 44px;
1194- border: 2px solid var(--dynamic-border);
1195- background-color: var(--dynamic-surface);
1438+ width: 38px;
1439+ height: 38px;
1440+ border: 1px solid var(--dynamic-border);
1441+ background-color: var(--dynamic-bg);
11961442 display: flex;
11971443 align-items: center;
11981444 justify-content: center;
11991445 flex-shrink: 0;
1200- border-radius: 0;
12011446 }
12021447
12031448 .history-favicon-img {
@@ -1215,21 +1460,22 @@
12151460 color: var(--dynamic-muted);
12161461 }
12171462
1463+.history-favicon-fallback svg {
1464+ opacity: 0.55;
1465+}
1466+
12181467 .history-item-content {
1219- flex: 1;
1220- min-width: 0;
12211468 display: flex;
12221469 flex-direction: column;
1223- gap: 0.25rem;
1224- justify-content: center;
1225- overflow: hidden;
1470+ gap: 0.2rem;
1471+ min-width: 0;
12261472 }
12271473
12281474 .history-item-main {
12291475 display: flex;
1230- align-items: flex-start;
1476+ align-items: center;
12311477 justify-content: space-between;
1232- gap: 1rem;
1478+ gap: 0.75rem;
12331479 }
12341480
12351481 .history-title {
@@ -1237,34 +1483,35 @@
12371483 color: var(--dynamic-text);
12381484 white-space: nowrap;
12391485 overflow: hidden;
1240- flex: 1;
1241- position: relative;
1242- mask-image: linear-gradient(to right, black 70%, transparent 100%);
1243- -webkit-mask-image: linear-gradient(to right, black 70%, transparent 100%);
12441486 }
12451487
1488+:global(.history-title.truncated) {
1489+ mask-image: linear-gradient(to right, black 85%, transparent 100%);
1490+ -webkit-mask-image: linear-gradient(to right, black 85%, transparent 100%);
1491+}
1492+
1493+.history-title:hover {
1494+ cursor: pointer;
1495+}
12461496
12471497 .history-time {
1248- font-size: 0.85rem;
1498+ font-size: 0.72rem;
12491499 color: var(--dynamic-muted);
1250- flex-shrink: 0;
1500+ text-transform: uppercase;
1501+ letter-spacing: 0.08em;
1502+ white-space: nowrap;
12511503 }
12521504
12531505 .history-url {
1254- font-size: 0.8rem;
1506+ font-size: 0.72rem;
12551507 color: var(--dynamic-muted);
12561508 white-space: nowrap;
1257- font-family:
1258- "JetBrains Mono",
1259- "SFMono-Regular",
1260- Menlo,
1261- monospace;
12621509 overflow: hidden;
1263- flex: 1;
1264- min-width: 0;
1265- position: relative;
1266- mask-image: linear-gradient(to right, black 70%, transparent 100%);
1267- -webkit-mask-image: linear-gradient(to right, black 70%, transparent 100%);
1510+}
1511+
1512+:global(.history-url.truncated) {
1513+ mask-image: linear-gradient(to right, black 85%, transparent 100%);
1514+ -webkit-mask-image: linear-gradient(to right, black 85%, transparent 100%);
12681515 }
12691516
12701517 .history-url :global(.history-url-domain) {
@@ -1274,364 +1521,313 @@
12741521
12751522 .history-actions {
12761523 display: flex;
1277- flex-shrink: 0;
1278-}
1279-
1280-.history-pin {
1281- display: flex;
1282- align-items: center;
1283- justify-content: center;
1284- width: 38px;
1285- border-left: 2px solid var(--dynamic-border);
1286- background-color: var(--dynamic-surface);
1287- color: var(--dynamic-muted);
1288- transition: background-color 200ms ease, color 200ms ease;
1289- cursor: pointer;
1290-}
1291-
1292-.history-pin:hover,
1293-.history-pin:focus-visible {
1294- color: var(--dynamic-accent);
1295- background-color: var(--dynamic-bg);
1296- outline: none;
1524+ gap: 0.35rem;
12971525 }
12981526
1527+.history-pin,
12991528 .history-delete {
1300- display: flex;
1529+ display: inline-flex;
13011530 align-items: center;
13021531 justify-content: center;
1303- width: 38px;
1304- border-left: 2px solid var(--dynamic-border);
1305- background-color: var(--dynamic-surface);
1532+ width: 28px;
1533+ height: 28px;
1534+ border: 1px solid var(--dynamic-border);
13061535 color: var(--dynamic-muted);
1307- font-size: 1.1rem;
1308- transition: background-color 200ms ease, color 200ms ease;
1309- flex-shrink: 0;
1536+ background: transparent;
1537+ transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
13101538 }
13111539
1540+.history-pin:hover,
1541+.history-pin:focus-visible,
13121542 .history-delete:hover,
13131543 .history-delete:focus-visible {
1314- color: var(--dynamic-accent);
1315- background-color: var(--dynamic-bg);
1544+ color: var(--dynamic-text);
1545+ border-color: color-mix(in srgb, var(--dynamic-border) 45%, var(--dynamic-text) 55%);
1546+ background: color-mix(in srgb, var(--dynamic-bg) 80%, var(--dynamic-surface) 20%);
13161547 outline: none;
13171548 }
13181549
13191550 .scroll-sentinel {
1320- width: 100%;
13211551 height: 1px;
13221552 }
13231553
13241554 .loading-more {
13251555 padding: 0.75rem;
1556+ font-size: 0.7rem;
13261557 text-align: center;
13271558 color: var(--dynamic-muted);
1328- font-size: 0.85rem;
1559+ letter-spacing: 0.08em;
1560+ text-transform: uppercase;
13291561 }
13301562
13311563 .quick-access-body {
1332- gap: 1rem;
1564+ gap: 0.9rem;
13331565 }
13341566
13351567 .quick-access-grid-compact {
13361568 display: flex;
13371569 flex-direction: column;
1338- gap: 0.5rem;
1339- background-color: var(--dynamic-surface-variant);
1340- border: 2px solid var(--dynamic-border);
1341- padding: 0.5rem;
1570+ gap: 0.75rem;
13421571 }
13431572
13441573 .quick-access-item-compact {
1345- display: flex;
1346- align-items: center;
1574+ border: 1px solid var(--dynamic-border);
1575+ background: color-mix(in srgb, var(--dynamic-bg) 92%, var(--dynamic-surface) 8%);
1576+ padding: 0.75rem 0.9rem;
1577+ display: grid;
1578+ grid-template-columns: auto 1fr auto;
13471579 gap: 0.75rem;
1348- border-bottom: 1px solid var(--dynamic-border);
1349- background-color: var(--dynamic-surface-variant);
1350- padding: 0.5rem 0.25rem;
1580+ align-items: center;
1581+ transition: background-color 150ms ease, border-color 150ms ease;
13511582 cursor: pointer;
1352- transition: background-color 200ms ease;
1353-}
1354-
1355-.quick-access-item-compact:last-child {
1356- border-bottom: none;
13571583 }
13581584
13591585 .quick-access-item-compact:hover,
13601586 .quick-access-item-compact:focus-visible {
1361- background-color: var(--dynamic-surface);
1587+ border-color: color-mix(in srgb, var(--dynamic-border) 45%, var(--dynamic-text) 55%);
1588+ background: color-mix(in srgb, var(--dynamic-bg) 70%, var(--dynamic-surface) 30%);
13621589 outline: none;
13631590 }
13641591
13651592 .quick-access-favicon-compact {
1366- width: 32px;
1367- height: 32px;
1368- border: 2px solid var(--dynamic-border);
1369- background-color: var(--dynamic-surface-variant);
1593+ width: 36px;
1594+ height: 36px;
1595+ border: 1px solid var(--dynamic-border);
13701596 display: flex;
13711597 align-items: center;
13721598 justify-content: center;
1373- flex-shrink: 0;
1374- border-radius: 0;
1599+ background: var(--dynamic-bg);
13751600 }
13761601
13771602 .quick-access-favicon-img-compact {
1378- width: 70%;
1379- height: 70%;
1603+ width: 60%;
1604+ height: 60%;
13801605 object-fit: contain;
13811606 }
13821607
13831608 .quick-access-fallback-compact {
1384- width: 100%;
1385- height: 100%;
13861609 display: flex;
13871610 align-items: center;
13881611 justify-content: center;
1612+ width: 100%;
1613+ height: 100%;
13891614 color: var(--dynamic-muted);
13901615 }
13911616
1617+.quick-access-fallback-compact svg {
1618+ opacity: 0.55;
1619+}
1620+
13921621 .quick-access-meta-compact {
1393- flex: 1;
1394- min-width: 0;
13951622 display: flex;
13961623 flex-direction: column;
1397- gap: 0.125rem;
1624+ gap: 0.2rem;
1625+ min-width: 0;
13981626 }
13991627
14001628 .quick-access-title-compact {
1401- font-size: 0.95rem;
1402- font-weight: 600;
14031629 color: var(--dynamic-text);
1630+ font-weight: 600;
14041631 white-space: nowrap;
14051632 overflow: hidden;
1406- position: relative;
1407- mask-image: linear-gradient(to right, black 70%, transparent 100%);
1408- -webkit-mask-image: linear-gradient(to right, black 70%, transparent 100%);
1633+}
1634+
1635+:global(.quick-access-title-compact.truncated) {
1636+ mask-image: linear-gradient(to right, black 85%, transparent 100%);
1637+ -webkit-mask-image: linear-gradient(to right, black 85%, transparent 100%);
1638+}
1639+
1640+.quick-access-title-compact:hover {
1641+ cursor: pointer;
14091642 }
14101643
14111644 .quick-access-domain-compact {
1412- font-size: 0.8rem;
14131645 color: var(--dynamic-muted);
1414- white-space: nowrap;
1415- overflow: hidden;
1416- text-overflow: ellipsis;
1646+ font-size: 0.72rem;
1647+ text-transform: uppercase;
1648+ letter-spacing: 0.08em;
14171649 }
14181650
14191651 .quick-access-actions-compact {
14201652 display: flex;
1421- align-items: center;
1422- gap: 0.5rem;
1423- flex-shrink: 0;
1653+ flex-direction: column;
1654+ gap: 0.3rem;
1655+ align-items: flex-end;
1656+ justify-content: center;
14241657 }
14251658
14261659 .quick-access-pin-compact {
1427- display: flex;
1660+ display: inline-flex;
14281661 align-items: center;
14291662 justify-content: center;
1430- width: 24px;
1431- height: 24px;
1663+ width: 26px;
1664+ height: 26px;
14321665 border: 1px solid var(--dynamic-border);
1433- background-color: var(--dynamic-surface-variant);
14341666 color: var(--dynamic-muted);
1435- transition: background-color 200ms ease, color 200ms ease;
1667+ background: transparent;
1668+ transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
14361669 cursor: pointer;
1437- border-radius: 0;
14381670 }
14391671
14401672 .quick-access-pin-compact:hover,
14411673 .quick-access-pin-compact:focus-visible {
1442- color: var(--dynamic-accent);
1443- background-color: var(--dynamic-surface);
1674+ color: var(--dynamic-text);
1675+ border-color: color-mix(in srgb, var(--dynamic-border) 45%, var(--dynamic-text) 55%);
1676+ background: color-mix(in srgb, var(--dynamic-bg) 80%, var(--dynamic-surface) 20%);
14441677 outline: none;
14451678 }
14461679
1447-.quick-access-visits-compact {
1448- font-size: 0.75rem;
1449- color: var(--dynamic-accent);
1450- text-transform: uppercase;
1451- letter-spacing: 0.05em;
1452- font-weight: 600;
1453- flex-shrink: 0;
1680+.quick-access-pin-compact svg {
1681+ width: 14px;
1682+ height: 14px;
14541683 }
14551684
1456-
1457-.stat-value {
1458- font-size: 1.4rem;
1459- font-weight: 600;
1460- color: var(--dynamic-text);
1685+.quick-access-visits-compact {
1686+ font-size: 0.7rem;
1687+ color: var(--dynamic-muted);
1688+ text-transform: uppercase;
1689+ letter-spacing: 0.08em;
14611690 }
14621691
1463-.stat-label {
1464- font-size: 0.8rem;
1692+.show-more-button {
1693+ width: 100%;
1694+ padding: 0.65rem 0.75rem;
1695+ border: 1px solid var(--dynamic-border);
1696+ background: transparent;
14651697 color: var(--dynamic-muted);
1698+ font-size: 0.72rem;
14661699 text-transform: uppercase;
14671700 letter-spacing: 0.08em;
1701+ cursor: pointer;
1702+ transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
1703+ border-radius: 0;
1704+}
1705+
1706+.show-more-button:hover,
1707+.show-more-button:focus-visible {
1708+ background: color-mix(in srgb, var(--dynamic-bg) 75%, var(--dynamic-surface) 25%);
1709+ color: var(--dynamic-text);
1710+ border-color: color-mix(in srgb, var(--dynamic-border) 45%, var(--dynamic-text) 55%);
1711+ outline: none;
14681712 }
14691713
14701714 .stats-grid-horizontal {
1471- display: flex;
1472- flex-wrap: wrap;
1473- gap: 1rem;
1474- justify-content: space-between;
1715+ display: grid;
1716+ gap: 0.85rem;
1717+ grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
14751718 }
14761719
14771720 .stat-item-horizontal {
1478- flex: 1;
1479- min-width: 120px;
1480- border: 2px solid var(--dynamic-border);
1481- background-color: var(--dynamic-surface-variant);
1482- padding: 0.75rem;
1721+ border: 1px solid var(--dynamic-border);
1722+ padding: 0.85rem;
14831723 display: flex;
14841724 flex-direction: column;
1485- gap: 0.25rem;
1486- text-align: center;
1487- border-radius: 0;
1725+ gap: 0.4rem;
1726+ background: color-mix(in srgb, var(--dynamic-bg) 92%, var(--dynamic-surface) 8%);
1727+ text-transform: uppercase;
1728+ letter-spacing: 0.08em;
1729+}
1730+
1731+.stat-value {
1732+ font-size: 0.95rem;
1733+ color: var(--dynamic-text);
1734+ font-weight: 600;
14881735 }
14891736
1490-.shortcuts-panel {
1491- gap: 0;
1737+.stat-label {
1738+ font-size: 0.68rem;
1739+ color: var(--dynamic-muted);
14921740 }
14931741
14941742 .shortcuts-list {
1495- display: flex;
1496- flex-wrap: wrap;
1497- gap: 0.85rem;
1743+ display: grid;
1744+ gap: 0.6rem;
14981745 }
14991746
15001747 .shortcut-item {
1501- display: flex;
1748+ display: grid;
1749+ grid-template-columns: auto 1fr;
1750+ gap: 0.6rem;
15021751 align-items: center;
1503- gap: 0.75rem;
1504- border: 2px solid var(--dynamic-border);
1505- background-color: var(--dynamic-bg);
1506- padding: 0.75rem 1rem;
1507- border-radius: 0;
1752+ border: 1px solid var(--dynamic-border);
1753+ padding: 0.6rem 0.75rem;
1754+ background: color-mix(in srgb, var(--dynamic-bg) 92%, var(--dynamic-surface) 8%);
15081755 }
15091756
15101757 .shortcut-key-badge {
1511- font-family:
1512- "JetBrains Mono",
1513- "SFMono-Regular",
1514- Menlo,
1515- monospace;
1516- font-size: 0.85rem;
1758+ font-size: 0.72rem;
15171759 text-transform: uppercase;
15181760 letter-spacing: 0.08em;
1519- padding: 0.35rem 0.65rem;
1520- border: 2px solid var(--dynamic-border);
1521- background-color: var(--dynamic-surface-variant);
1522- color: var(--dynamic-muted);
1523- font-weight: 500;
1524- border-radius: 0;
1525-}
1526-
1527-.shortcut-desc {
1528- font-size: 0.95rem;
1761+ padding: 0.25rem 0.6rem;
1762+ border: 1px solid var(--dynamic-border);
15291763 color: var(--dynamic-text);
1764+ background: color-mix(in srgb, var(--dynamic-bg) 80%, var(--dynamic-surface) 20%);
15301765 }
15311766
1532-.shortcuts-panel .loading {
1533- border-style: solid;
1767+.shortcut-desc {
1768+ font-size: 0.72rem;
1769+ color: var(--dynamic-muted);
1770+ letter-spacing: 0.06em;
15341771 }
15351772
1536-/* Responsive Design */
1537-@media (max-width: 1200px) {
1538- .history-panel,
1539- .quick-access-panel {
1540- min-width: min(28rem, 100%);
1773+@media (max-width: 960px) {
1774+ .terminal-body {
1775+ padding: 1.1rem;
15411776 }
1542-}
15431777
1544-@media (max-width: 960px) {
1545- .homepage-shell {
1546- padding: clamp(1.25rem, 5vw, 2rem);
1778+ .terminal-grid {
1779+ gap: 0.75rem;
15471780 }
15481781
15491782 .main-panels {
1550- flex-direction: column;
1783+ grid-template-columns: 1fr;
15511784 }
15521785
1553- .history-panel,
1554- .quick-access-panel {
1555- min-width: 100%;
1556- max-width: 100%;
1557- width: 100%;
1786+ .last-visit-banner {
1787+ grid-template-columns: minmax(0, auto) minmax(0, 1fr);
1788+ grid-template-rows: repeat(3, auto);
1789+ gap: 0.5rem 0.75rem;
15581790 }
15591791
1792+ .banner-time,
1793+ .banner-absolute {
1794+ justify-self: flex-start;
1795+ }
15601796 }
15611797
15621798 @media (max-width: 640px) {
1563- .theme-toggle-button {
1564- width: 2.75rem;
1565- height: 2.75rem;
1566- }
1567-
1568- .panel-body,
1569- .panel-header {
1570- padding-left: 1.25rem;
1571- padding-right: 1.25rem;
1799+ .homepage-shell {
1800+ padding: 1.25rem;
15721801 }
15731802
1574-
1575- .history-item {
1803+ .terminal-header {
15761804 flex-direction: column;
15771805 align-items: flex-start;
15781806 }
15791807
1580- .history-actions {
1581- width: 100%;
1582- border-top: 2px solid var(--dynamic-border);
1808+ .theme-toggle-button {
1809+ align-self: flex-end;
15831810 }
15841811
1585- .history-pin,
1586- .history-delete {
1587- flex: 1;
1588- border-left: 0;
1812+ .terminal-status-row {
1813+ gap: 0.5rem;
15891814 }
15901815
1591- .history-pin {
1592- border-right: 1px solid var(--dynamic-border);
1816+ .status-chip {
1817+ padding: 0.35rem 0.65rem;
15931818 }
15941819
1595- .history-item-main {
1596- flex-direction: column;
1597- align-items: flex-start;
1598- gap: 0.35rem;
1820+ .last-visit-banner {
1821+ grid-template-columns: minmax(0, 1fr);
1822+ grid-template-rows: repeat(4, auto);
15991823 }
16001824
1601- .history-time {
1602- order: 3;
1825+ .banner-label,
1826+ .banner-title,
1827+ .banner-domain,
1828+ .banner-time,
1829+ .banner-absolute {
1830+ justify-self: flex-start;
16031831 }
1604-
1605- .stats-grid-horizontal {
1606- flex-direction: column;
1607- gap: 0.75rem;
1608- }
1609-
1610- .stat-item-horizontal {
1611- min-width: 100%;
1612- }
1613-}
1614-
1615-.show-more-button {
1616- width: 100%;
1617- padding: 0.75rem 1rem;
1618- border: 2px solid var(--dynamic-border);
1619- background-color: var(--dynamic-surface-variant);
1620- color: var(--dynamic-text);
1621- font-size: 0.9rem;
1622- font-weight: 500;
1623- cursor: pointer;
1624- transition:
1625- background-color 200ms ease,
1626- border-color 200ms ease;
1627- border-radius: 0;
1628- margin-top: 0.5rem;
1629-}
1630-
1631-.show-more-button:hover,
1632-.show-more-button:focus-visible {
1633- background-color: var(--dynamic-surface);
1634- border-color: var(--dynamic-accent);
1635- outline: none;
16361832 }
16371833 </style>
@@ -482,6 +482,39 @@
482 482
483 let quickAccess = $derived<HistoryItem[]>((pinnedSites.size, buildQuickAccess()));483 let quickAccess = $derived<HistoryItem[]>((pinnedSites.size, buildQuickAccess()));
484 let quickAccessLoading = $derived(topVisitedLoading || historyLoading);484 let quickAccessLoading = $derived(topVisitedLoading || historyLoading);
485+ interface LatestVisitMeta {
486+ entry: HistoryItem;
487+ relative: string;
488+ absolute: string;
489+ domain: string;
490+ title: string;
491+ }
492+
493+ const latestVisitInfo = $derived<LatestVisitMeta | null>((() => {
494+ if (!historyItems.length) return null;
495+
496+ let latest: HistoryItem | null = null;
497+ let latestEpoch = Number.NEGATIVE_INFINITY;
498+
499+ for (const entry of historyItems) {
500+ const epoch = Number(new Date(entry.last_visited));
501+ if (!Number.isFinite(epoch)) continue;
502+ if (epoch > latestEpoch) {
503+ latest = entry;
504+ latestEpoch = epoch;
505+ }
506+ }
507+
508+ if (!latest) return null;
509+
510+ return {
511+ entry: latest,
512+ relative: formatTime(latest.last_visited),
513+ absolute: formatCalendarDate(latest.last_visited),
514+ domain: getDomain(latest.url),
515+ title: getDisplayTitle(latest)
516+ };
517+ })());
485 518
486 const persistTheme = (mode: ThemeMode) => {519 const persistTheme = (mode: ThemeMode) => {
487 try {520 try {
@@ -613,6 +646,28 @@
613 return () => observer.disconnect();646 return () => observer.disconnect();
614 };647 };
615 648
649+ // Helper to check if text overflows and apply truncation class
650+ const checkOverflow = (node: HTMLElement) => {
651+ const check = () => {
652+ if (node.scrollWidth > node.clientWidth) {
653+ node.classList.add('truncated');
654+ } else {
655+ node.classList.remove('truncated');
656+ }
657+ };
658+
659+ check();
660+
661+ const resizeObserver = new ResizeObserver(check);
662+ resizeObserver.observe(node);
663+
664+ return {
665+ destroy() {
666+ resizeObserver.disconnect();
667+ }
668+ };
669+ };
670+
616 onMount(() => {671 onMount(() => {
617 loadPinnedSites();672 loadPinnedSites();
618 initializeShortcuts();673 initializeShortcuts();
@@ -651,8 +706,16 @@
651 </svelte:head>706 </svelte:head>
652 707
653 <div class="homepage-shell">708 <div class="homepage-shell">
654- <div class="homepage-content">709+ <div class="terminal-frame">
655- <div class="top-bar">710+ <header class="terminal-header">
711+ <div class="terminal-heading">
712+ <span class="terminal-path">dumb://home</span>
713+ <span class="terminal-meta">
714+ {statsLoading ? 'syncing…' : `${stats?.recent_count ?? 0} recent`}
715+ · {historyItems.length} entries
716+ · {pinnedSites.size} pinned
717+ </span>
718+ </div>
656 <button719 <button
657 class="theme-toggle-button"720 class="theme-toggle-button"
658 type="button"721 type="button"
@@ -667,7 +730,9 @@
667 <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">730 <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
668 <path731 <path
669 fill="currentColor"732 fill="currentColor"
670- d="M21 12.79A9 9 0 0111.21 3 7 7 0 0012 17a7 7 0 009-4.21z"733+ fill-rule="evenodd"
734+ clip-rule="evenodd"
735+ d="M17.293 13.293A8 8 0 0 1 10.707 2.997a8.001 8.001 0 1 0 6.586 10.296z"
671 />736 />
672 </svg>737 </svg>
673 {:else}738 {:else}
@@ -686,9 +751,57 @@
686 </svg>751 </svg>
687 {/if}752 {/if}
688 </button>753 </button>
689- </div>754+ </header>
690- <div class="main-panels">755+
691- <section class="history-panel brutal-panel">756+ <div class="terminal-body">
757+ <div class="terminal-status-row">
758+ <div class="status-chip">
759+ <span class="chip-label">history</span>
760+ <span class="chip-value">{historyItems.length}</span>
761+ </div>
762+ <div class="status-chip">
763+ <span class="chip-label">pinned</span>
764+ <span class="chip-value">{pinnedSites.size}</span>
765+ </div>
766+ <div class="status-chip">
767+ <span class="chip-label">quick-links</span>
768+ <span class="chip-value">{quickAccess.length}</span>
769+ </div>
770+ {#if stats && stats.total_entries}
771+ <div class="status-chip">
772+ <span class="chip-label">stored</span>
773+ <span class="chip-value">{stats.total_entries}</span>
774+ </div>
775+ {/if}
776+ </div>
777+
778+ <div
779+ class="last-visit-banner"
780+ role="button"
781+ tabindex={latestVisitInfo ? 0 : -1}
782+ onclick={() => latestVisitInfo && navigateTo(latestVisitInfo.entry.url)}
783+ onkeydown={(event) => {
784+ if (event.key === 'Enter' && latestVisitInfo) {
785+ navigateTo(latestVisitInfo.entry.url);
786+ }
787+ }}
788+ aria-label={latestVisitInfo ? `Open ${latestVisitInfo.title}` : 'No recorded visits'}
789+ >
790+ <span class="banner-label">last-visit</span>
791+ {#if latestVisitInfo}
792+ <span class="banner-title" use:checkOverflow>
793+ {latestVisitInfo.title}
794+ </span>
795+ <span class="banner-domain">{latestVisitInfo.domain}</span>
796+ <span class="banner-time">{latestVisitInfo.relative}</span>
797+ <span class="banner-absolute">{latestVisitInfo.absolute}</span>
798+ {:else}
799+ <span class="banner-empty">none recorded yet</span>
800+ {/if}
801+ </div>
802+
803+ <div class="terminal-grid main-panels">
804+ <section class="history-panel terminal-pane">
692 <div class="panel-header">805 <div class="panel-header">
693 <h2 class="panel-title">Recent History</h2>806 <h2 class="panel-title">Recent History</h2>
694 <p class="panel-subtitle">Scroll to revisit anything from your latest sessions.</p>807 <p class="panel-subtitle">Scroll to revisit anything from your latest sessions.</p>
@@ -751,10 +864,14 @@
751 </div>864 </div>
752 <div class="history-item-content">865 <div class="history-item-content">
753 <div class="history-item-main">866 <div class="history-item-main">
754- <div class="history-title">{getDisplayTitle(item)}</div>867+ <div class="history-title" use:checkOverflow>
868+ {getDisplayTitle(item)}
869+ </div>
755 <div class="history-time">{formatTime(item.last_visited)}</div>870 <div class="history-time">{formatTime(item.last_visited)}</div>
756 </div>871 </div>
757- <div class="history-url">{@html highlightDomainInUrl(item.url)}</div>872+ <div class="history-url" use:checkOverflow>
873+ {@html highlightDomainInUrl(item.url)}
874+ </div>
758 </div>875 </div>
759 <div class="history-actions">876 <div class="history-actions">
760 <div877 <div
@@ -770,7 +887,7 @@
770 <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>887 <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
771 </svg>888 </svg>
772 {:else}889 {:else}
773- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">890+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round" stroke-linecap="round" aria-hidden="true">
774 <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>891 <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
775 </svg>892 </svg>
776 {/if}893 {/if}
@@ -808,7 +925,7 @@
808 </div>925 </div>
809 </section>926 </section>
810 927
811- <section class="quick-access-panel brutal-panel">928+ <section class="quick-access-panel terminal-pane">
812 <div class="panel-header">929 <div class="panel-header">
813 <h2 class="panel-title">Jump back in</h2>930 <h2 class="panel-title">Jump back in</h2>
814 <p class="panel-subtitle">Direct access to the sites you like the most.</p>931 <p class="panel-subtitle">Direct access to the sites you like the most.</p>
@@ -869,7 +986,9 @@
869 {/if}986 {/if}
870 </div>987 </div>
871 <div class="quick-access-meta-compact">988 <div class="quick-access-meta-compact">
872- <div class="quick-access-title-compact">{getDisplayTitle(item)}</div>989+ <div class="quick-access-title-compact" use:checkOverflow>
990+ {getDisplayTitle(item)}
991+ </div>
873 <div class="quick-access-domain-compact">{getDomain(item.url)}</div>992 <div class="quick-access-domain-compact">{getDomain(item.url)}</div>
874 </div>993 </div>
875 <div class="quick-access-actions-compact">994 <div class="quick-access-actions-compact">
@@ -886,7 +1005,7 @@
886 <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>1005 <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
887 </svg>1006 </svg>
888 {:else}1007 {:else}
889- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">1008+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round" stroke-linecap="round" aria-hidden="true">
890 <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>1009 <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
891 </svg>1010 </svg>
892 {/if}1011 {/if}
@@ -899,132 +1018,165 @@
899 {/if}1018 {/if}
900 </div>1019 </div>
901 </section>1020 </section>
902- </div>
903-
904- <section class="shortcuts-panel brutal-panel">
905- <div class="panel-header">
906- <h2 class="panel-title">Keyboard Shortcuts</h2>
907- <p class="panel-subtitle">Stay quick with the essentials.</p>
908- </div>
909- <div class="panel-body">
910- {#if shortcutsLoading}
911- <div class="loading">Loading shortcuts...</div>
912- {:else}
913- <div class="shortcuts-list">
914- {#each shortcuts as shortcut (shortcut.key)}
915- <div class="shortcut-item">
916- <div class="shortcut-key-badge">{shortcut.key}</div>
917- <div class="shortcut-desc">{shortcut.description}</div>
918- </div>
919- {/each}
920- </div>
921- {/if}
922 </div>1021 </div>
923- </section>
924 1022
925-1023+ <div class="terminal-grid supporting-panels">
926- <section class="stats-panel brutal-panel">1024+ <section class="stats-panel terminal-pane">
927- <div class="panel-header">1025+ <div class="panel-header">
928- <h2 class="panel-title">Usage Stats</h2>1026+ <h2 class="panel-title">Usage Stats</h2>
929- <p class="panel-subtitle">Your browsing activity at a glance.</p>1027+ <p class="panel-subtitle">Your browsing activity at a glance.</p>
930- </div>1028+ </div>
931- <div class="panel-body">1029+ <div class="panel-body">
932- {#if statsLoading}1030+ {#if statsLoading}
933- <div class="loading">Loading stats...</div>1031+ <div class="loading">Loading stats...</div>
934- {:else if stats}1032+ {:else if stats}
935- <div class="stats-grid-horizontal">1033+ <div class="stats-grid-horizontal">
936- <div class="stat-item-horizontal">1034+ <div class="stat-item-horizontal">
937- <div class="stat-value">{stats.total_entries}</div>1035+ <div class="stat-value">{stats.total_entries}</div>
938- <div class="stat-label">Entries Stored</div>1036+ <div class="stat-label">Entries Stored</div>
939- </div>1037+ </div>
940- <div class="stat-item-horizontal">1038+ <div class="stat-item-horizontal">
941- <div class="stat-value">{stats.recent_count}</div>1039+ <div class="stat-value">{stats.recent_count}</div>
942- <div class="stat-label">Recent Window</div>1040+ <div class="stat-label">Recent Window</div>
943- </div>1041+ </div>
944- {#if stats.newest_entry}1042+ {#if stats.newest_entry}
945- <div class="stat-item-horizontal">1043+ <div class="stat-item-horizontal">
946- <div class="stat-value">{formatTime(stats.newest_entry)}</div>1044+ <div class="stat-value">{formatTime(stats.newest_entry)}</div>
947- <div class="stat-label">Newest Visit</div>1045+ <div class="stat-label">Newest Visit</div>
1046+ </div>
1047+ {/if}
1048+ {#if stats.oldest_entry}
1049+ <div class="stat-item-horizontal">
1050+ <div class="stat-value">{formatCalendarDate(stats.oldest_entry)}</div>
1051+ <div class="stat-label">Oldest Entry</div>
1052+ </div>
1053+ {/if}
948 </div>1054 </div>
949- {/if}1055+ {:else}
950- {#if stats.oldest_entry}1056+ <div class="empty-state compact">
951- <div class="stat-item-horizontal">1057+ <p>No statistics available</p>
952- <div class="stat-value">{formatCalendarDate(stats.oldest_entry)}</div>
953- <div class="stat-label">Oldest Entry</div>
954 </div>1058 </div>
955 {/if}1059 {/if}
956 </div>1060 </div>
957- {:else}1061+ </section>
958- <div class="empty-state compact">1062+
959- <p>No statistics available</p>1063+ <section class="shortcuts-panel terminal-pane">
1064+ <div class="panel-header">
1065+ <h2 class="panel-title">Keyboard Shortcuts</h2>
1066+ <p class="panel-subtitle">Stay quick with the essentials.</p>
960 </div>1067 </div>
961- {/if}1068+ <div class="panel-body">
1069+ {#if shortcutsLoading}
1070+ <div class="loading">Loading shortcuts...</div>
1071+ {:else}
1072+ <div class="shortcuts-list">
1073+ {#each shortcuts as shortcut (shortcut.key)}
1074+ <div class="shortcut-item">
1075+ <div class="shortcut-key-badge">{shortcut.key}</div>
1076+ <div class="shortcut-desc">{shortcut.description}</div>
1077+ </div>
1078+ {/each}
1079+ </div>
1080+ {/if}
1081+ </div>
1082+ </section>
962 </div>1083 </div>
963- </section>1084+ </div>
964-
965 </div>1085 </div>
966 1086
967 <Footer />1087 <Footer />
968 </div>1088 </div>
969 1089
970 <style>1090 <style>
971-/* Homepage Layout Styles */
972 .homepage-shell {1091 .homepage-shell {
973 min-height: 100vh;1092 min-height: 100vh;
974 background-color: var(--dynamic-bg);1093 background-color: var(--dynamic-bg);
975 color: var(--dynamic-text);1094 color: var(--dynamic-text);
976 display: flex;1095 display: flex;
977 flex-direction: column;1096 flex-direction: column;
978- padding: clamp(1.75rem, 3vw, 3rem);1097+ padding: clamp(1.5rem, 4vw, 2.5rem);
979- font-family: "Fira Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;1098+ font-family:
1099+ "JetBrains Mono",
1100+ "Fira Code",
1101+ "SFMono-Regular",
1102+ Menlo,
1103+ monospace;
1104+ line-height: 1.45;
980 }1105 }
981 1106
982 .homepage-shell * {1107 .homepage-shell * {
983 box-sizing: border-box;1108 box-sizing: border-box;
984 }1109 }
985 1110
986-.homepage-content {1111+.terminal-frame {
987 flex: 1;1112 flex: 1;
988 width: 100%;1113 width: 100%;
989- max-width: 1180px;1114+ max-width: 1160px;
990 margin: 0 auto;1115 margin: 0 auto;
991 display: flex;1116 display: flex;
992 flex-direction: column;1117 flex-direction: column;
993- gap: clamp(1.75rem, 2.6vw, 2.75rem);1118+ border: 1px solid var(--dynamic-border);
1119+ background: color-mix(in srgb, var(--dynamic-surface) 80%, var(--dynamic-bg) 20%);
1120+ box-shadow:
1121+ inset 0 0 0 1px color-mix(in srgb, var(--dynamic-border) 30%, transparent),
1122+ 0 16px 28px -24px rgb(0 0 0 / 0.6);
1123+}
1124+
1125+.terminal-header {
1126+ display: flex;
1127+ align-items: center;
1128+ justify-content: space-between;
1129+ gap: 1rem;
1130+ padding: 0.85rem 1.1rem;
1131+ border-bottom: 1px solid var(--dynamic-border);
1132+ background: color-mix(in srgb, var(--dynamic-bg) 92%, var(--dynamic-surface) 8%);
1133+ text-transform: uppercase;
1134+ letter-spacing: 0.08em;
1135+ font-size: 0.78rem;
994 }1136 }
995 1137
996-.top-bar {1138+.terminal-heading {
997 display: flex;1139 display: flex;
998- justify-content: flex-end;1140+ flex-direction: column;
1141+ gap: 0.35rem;
1142+}
1143+
1144+.terminal-path {
1145+ font-weight: 600;
1146+ color: var(--dynamic-text);
1147+}
1148+
1149+.terminal-meta {
1150+ color: var(--dynamic-muted);
1151+ font-size: 0.72rem;
1152+ letter-spacing: 0.12em;
999 }1153 }
1000 1154
1001 .theme-toggle-button {1155 .theme-toggle-button {
1002- width: 3rem;1156+ width: 2.5rem;
1003- height: 3rem;1157+ height: 2.5rem;
1004 display: inline-flex;1158 display: inline-flex;
1005 align-items: center;1159 align-items: center;
1006 justify-content: center;1160 justify-content: center;
1007- border: 2px solid var(--dynamic-border);1161+ border: 1px solid var(--dynamic-border);
1162+ background-color: var(--dynamic-bg);
1163+ color: var(--dynamic-muted);
1164+ transition: color 150ms ease, border-color 150ms ease, background-color 150ms ease;
1008 border-radius: 0;1165 border-radius: 0;
1009- background-color: var(--dynamic-surface);
1010- color: var(--dynamic-text);
1011- transition:
1012- background-color 200ms ease,
1013- color 200ms ease,
1014- border-color 200ms ease;
1015 cursor: pointer;1166 cursor: pointer;
1016 }1167 }
1017 1168
1018 .theme-toggle-button:hover,1169 .theme-toggle-button:hover,
1019 .theme-toggle-button:focus-visible {1170 .theme-toggle-button:focus-visible {
1020- border-color: var(--dynamic-accent);1171+ border-color: color-mix(in srgb, var(--dynamic-border) 45%, var(--dynamic-text) 55%);
1021- color: var(--dynamic-accent);1172+ color: var(--dynamic-text);
1173+ background-color: color-mix(in srgb, var(--dynamic-bg) 80%, var(--dynamic-surface) 20%);
1022 outline: none;1174 outline: none;
1023 }1175 }
1024 1176
1025 .theme-toggle-button svg {1177 .theme-toggle-button svg {
1026- width: 1.5rem;1178+ width: 1.3rem;
1027- height: 1.5rem;1179+ height: 1.3rem;
1028 }1180 }
1029 1181
1030 .sr-only {1182 .sr-only {
@@ -1039,99 +1191,158 @@
1039 border: 0;1191 border: 0;
1040 }1192 }
1041 1193
1042-.brutal-panel {1194+.terminal-body {
1043- border: 2px solid var(--dynamic-border);
1044- background-color: var(--dynamic-surface);
1045- border-radius: 0;
1046 display: flex;1195 display: flex;
1047 flex-direction: column;1196 flex-direction: column;
1048- gap: 0;1197+ gap: 1.25rem;
1198+ padding: 1.25rem 1.5rem 1.5rem;
1199+ background: var(--dynamic-bg);
1049 }1200 }
1050 1201
1202+.terminal-status-row {
1203+ display: flex;
1204+ flex-wrap: wrap;
1205+ gap: 0.75rem;
1206+}
1051 1207
1052-1208+.status-chip {
1053-.loading {1209+ display: inline-flex;
1054- padding: 1.25rem;1210+ align-items: center;
1055- text-align: center;1211+ gap: 0.5rem;
1212+ padding: 0.45rem 0.8rem;
1213+ border: 1px solid var(--dynamic-border);
1214+ background: color-mix(in srgb, var(--dynamic-bg) 92%, var(--dynamic-surface) 8%);
1215+ font-size: 0.68rem;
1216+ letter-spacing: 0.1em;
1217+ text-transform: uppercase;
1056 color: var(--dynamic-muted);1218 color: var(--dynamic-muted);
1057- border: 2px dashed var(--dynamic-border);
1058- background-color: var(--dynamic-bg);
1059 }1219 }
1060 1220
1061-.empty-state {1221+.status-chip .chip-value {
1062- border: 2px dashed var(--dynamic-border);1222+ color: var(--dynamic-text);
1063- padding: 1.75rem;1223+ font-weight: 600;
1064- display: flex;1224+}
1065- flex-direction: column;1225+
1066- gap: 0.5rem;1226+.last-visit-banner {
1067- text-align: center;1227+ margin-top: 0.9rem;
1228+ display: grid;
1229+ grid-template-columns: minmax(0, auto) minmax(0, 1fr) minmax(120px, auto) minmax(120px, auto) minmax(120px, auto);
1230+ gap: 0.75rem;
1068 align-items: center;1231 align-items: center;
1232+ padding: 0.75rem 1rem;
1233+ border: 1px solid var(--dynamic-border);
1234+ background: color-mix(in srgb, var(--dynamic-bg) 90%, var(--dynamic-surface) 10%);
1235+ color: var(--dynamic-text);
1236+ text-transform: uppercase;
1237+ letter-spacing: 0.08em;
1238+ transition: background-color 150ms ease, border-color 150ms ease;
1239+ cursor: pointer;
1240+}
1241+
1242+.last-visit-banner:hover,
1243+.last-visit-banner:focus-visible {
1244+ background: color-mix(in srgb, var(--dynamic-bg) 72%, var(--dynamic-surface) 28%);
1245+ border-color: color-mix(in srgb, var(--dynamic-border) 45%, var(--dynamic-text) 55%);
1246+ outline: none;
1247+}
1248+
1249+.last-visit-banner[tabindex="-1"],
1250+.last-visit-banner[tabindex="-1"]:hover {
1251+ cursor: default;
1252+ background: color-mix(in srgb, var(--dynamic-bg) 95%, var(--dynamic-surface) 5%);
1253+}
1254+
1255+.banner-label {
1069 color: var(--dynamic-muted);1256 color: var(--dynamic-muted);
1070- background-color: var(--dynamic-bg);1257+ font-size: 0.68rem;
1071 }1258 }
1072 1259
1073-.empty-state h3 {1260+.banner-title {
1074- margin: 0;1261+ font-weight: 600;
1262+ white-space: nowrap;
1263+ overflow: hidden;
1264+ letter-spacing: 0.06em;
1265+}
1266+
1267+:global(.banner-title.truncated) {
1268+ mask-image: linear-gradient(to right, black 85%, transparent 100%);
1269+ -webkit-mask-image: linear-gradient(to right, black 85%, transparent 100%);
1270+}
1271+
1272+.banner-domain {
1273+ color: var(--dynamic-muted);
1274+ font-size: 0.68rem;
1275+ letter-spacing: 0.1em;
1276+}
1277+
1278+.banner-time {
1279+ font-size: 0.72rem;
1075 color: var(--dynamic-text);1280 color: var(--dynamic-text);
1076- font-size: 1.1rem;1281+ white-space: nowrap;
1077 }1282 }
1078 1283
1079-.empty-state p {1284+.banner-absolute {
1080- margin: 0;1285+ font-size: 0.68rem;
1081 color: var(--dynamic-muted);1286 color: var(--dynamic-muted);
1287+ white-space: nowrap;
1082 }1288 }
1083 1289
1084-.empty-state.compact {1290+.banner-empty {
1085- padding: 1.25rem;1291+ grid-column: 2 / -1;
1292+ color: var(--dynamic-muted);
1293+ font-size: 0.72rem;
1294+ letter-spacing: 0.1em;
1295+}
1296+
1297+.terminal-grid {
1298+ display: grid;
1299+ gap: 1rem;
1086 }1300 }
1087 1301
1088-/* Main panels with height matching */
1089 .main-panels {1302 .main-panels {
1090- display: flex;1303+ grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
1091- flex-wrap: wrap;
1092- gap: clamp(1.5rem, 2vw, 2rem);
1093- align-items: flex-start;
1094 }1304 }
1095 1305
1096-.history-panel {1306+.supporting-panels {
1097- flex: 1 1 55%;1307+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
1098- min-width: min(32rem, 100%);
1099- display: flex;
1100- flex-direction: column;
1101- min-height: 0;
1102 }1308 }
1103 1309
1104-.quick-access-panel {1310+.terminal-pane {
1105- flex: 1 1 35%;1311+ border: 1px solid var(--dynamic-border);
1106- min-width: min(24rem, 100%);1312+ background: color-mix(in srgb, var(--dynamic-bg) 88%, var(--dynamic-surface) 12%);
1107 display: flex;1313 display: flex;
1108 flex-direction: column;1314 flex-direction: column;
1109 min-height: 0;1315 min-height: 0;
1316+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dynamic-border) 18%, transparent);
1110 }1317 }
1111 1318
1112 .panel-header {1319 .panel-header {
1113 display: flex;1320 display: flex;
1114 flex-direction: column;1321 flex-direction: column;
1115- gap: 0.4rem;1322+ gap: 0.3rem;
1116- padding: clamp(1.25rem, 2vw, 1.75rem) clamp(1.5rem, 2.5vw, 2rem);1323+ padding: 1rem 1.1rem;
1117- border-bottom: 2px solid var(--dynamic-border);1324+ border-bottom: 1px solid var(--dynamic-border);
1118- background-color: var(--dynamic-surface);1325+ background: color-mix(in srgb, var(--dynamic-bg) 75%, transparent);
1119 }1326 }
1120 1327
1121 .panel-title {1328 .panel-title {
1122 margin: 0;1329 margin: 0;
1123- font-size: 1.3rem;1330+ font-size: 0.95rem;
1124- font-weight: 600;1331+ text-transform: uppercase;
1332+ letter-spacing: 0.08em;
1333+ color: var(--dynamic-text);
1125 }1334 }
1126 1335
1127 .panel-subtitle {1336 .panel-subtitle {
1128 margin: 0;1337 margin: 0;
1129- font-size: 0.95rem;1338+ font-size: 0.72rem;
1130 color: var(--dynamic-muted);1339 color: var(--dynamic-muted);
1340+ letter-spacing: 0.1em;
1341+ text-transform: uppercase;
1131 }1342 }
1132 1343
1133 .panel-body {1344 .panel-body {
1134- padding: clamp(1.25rem, 2vw, 1.75rem) clamp(1.5rem, 2.5vw, 2rem);1345+ padding: 1.1rem 1.1rem 1.25rem;
1135 display: flex;1346 display: flex;
1136 flex-direction: column;1347 flex-direction: column;
1137 gap: 1.1rem;1348 gap: 1.1rem;
@@ -1139,8 +1350,48 @@
1139 overflow: hidden;1350 overflow: hidden;
1140 }1351 }
1141 1352
1353+.loading {
1354+ padding: 0.9rem;
1355+ text-align: center;
1356+ color: var(--dynamic-muted);
1357+ border: 1px dashed var(--dynamic-border);
1358+ background-color: color-mix(in srgb, var(--dynamic-bg) 85%, var(--dynamic-surface) 15%);
1359+ text-transform: uppercase;
1360+ letter-spacing: 0.08em;
1361+ font-size: 0.7rem;
1362+}
1363+
1364+.empty-state {
1365+ border: 1px dashed var(--dynamic-border);
1366+ padding: 1.4rem;
1367+ display: flex;
1368+ flex-direction: column;
1369+ gap: 0.5rem;
1370+ align-items: center;
1371+ text-align: center;
1372+ color: var(--dynamic-muted);
1373+ background-color: color-mix(in srgb, var(--dynamic-bg) 90%, var(--dynamic-surface) 10%);
1374+ letter-spacing: 0.06em;
1375+}
1376+
1377+.empty-state h3 {
1378+ margin: 0;
1379+ color: var(--dynamic-text);
1380+ font-size: 0.9rem;
1381+ text-transform: uppercase;
1382+}
1383+
1384+.empty-state p {
1385+ margin: 0;
1386+ font-size: 0.72rem;
1387+}
1388+
1389+.empty-state.compact {
1390+ padding: 1rem;
1391+}
1392+
1142 .history-body {1393 .history-body {
1143- gap: 1rem;1394+ gap: 0.75rem;
1144 display: flex;1395 display: flex;
1145 flex-direction: column;1396 flex-direction: column;
1146 min-height: 0;1397 min-height: 0;
@@ -1150,26 +1401,21 @@
1150 .history-list {1401 .history-list {
1151 display: flex;1402 display: flex;
1152 flex-direction: column;1403 flex-direction: column;
1153- gap: 0.85rem;
1154 flex: 1;1404 flex: 1;
1155 min-height: 0;1405 min-height: 0;
1156 overflow-y: auto;1406 overflow-y: auto;
1157- background-color: var(--dynamic-surface-variant);1407+ border: 1px solid var(--dynamic-border);
1158- border: 2px solid var(--dynamic-border);1408+ background: color-mix(in srgb, var(--dynamic-bg) 95%, var(--dynamic-surface) 5%);
1159- padding: 0.5rem;
1160 }1409 }
1161 1410
1162 .history-item {1411 .history-item {
1163- display: flex;1412+ display: grid;
1164- align-items: flex-start;1413+ grid-template-columns: auto 1fr auto;
1414+ align-items: center;
1165 gap: 0.75rem;1415 gap: 0.75rem;
1166- border-bottom: 1px solid var(--dynamic-border);1416+ padding: 0.6rem 0.9rem;
1167- background-color: var(--dynamic-surface-variant);1417+ border-bottom: 1px dashed var(--dynamic-border);
1168- padding: 0.75rem 0.5rem;1418+ transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease;
1169- cursor: pointer;
1170- transition:
1171- background-color 200ms ease,
1172- border-color 200ms ease;
1173 }1419 }
1174 1420
1175 .history-item:last-child {1421 .history-item:last-child {
@@ -1178,26 +1424,25 @@
1178 1424
1179 .history-item:hover,1425 .history-item:hover,
1180 .history-item:focus-visible {1426 .history-item:focus-visible {
1181- background-color: var(--dynamic-surface);1427+ background: color-mix(in srgb, var(--dynamic-bg) 65%, var(--dynamic-surface) 35%);
1182 outline: none;1428 outline: none;
1183 }1429 }
1184 1430
1185 .history-item.deleting {1431 .history-item.deleting {
1186- opacity: 0.4;1432+ opacity: 0.35;
1187 pointer-events: none;1433 pointer-events: none;
1188- transform: translateX(6px);1434+ transform: translateX(4px);
1189 }1435 }
1190 1436
1191 .history-item-leading {1437 .history-item-leading {
1192- width: 44px;1438+ width: 38px;
1193- height: 44px;1439+ height: 38px;
1194- border: 2px solid var(--dynamic-border);1440+ border: 1px solid var(--dynamic-border);
1195- background-color: var(--dynamic-surface);1441+ background-color: var(--dynamic-bg);
1196 display: flex;1442 display: flex;
1197 align-items: center;1443 align-items: center;
1198 justify-content: center;1444 justify-content: center;
1199 flex-shrink: 0;1445 flex-shrink: 0;
1200- border-radius: 0;
1201 }1446 }
1202 1447
1203 .history-favicon-img {1448 .history-favicon-img {
@@ -1215,21 +1460,22 @@
1215 color: var(--dynamic-muted);1460 color: var(--dynamic-muted);
1216 }1461 }
1217 1462
1463+.history-favicon-fallback svg {
1464+ opacity: 0.55;
1465+}
1466+
1218 .history-item-content {1467 .history-item-content {
1219- flex: 1;
1220- min-width: 0;
1221 display: flex;1468 display: flex;
1222 flex-direction: column;1469 flex-direction: column;
1223- gap: 0.25rem;1470+ gap: 0.2rem;
1224- justify-content: center;1471+ min-width: 0;
1225- overflow: hidden;
1226 }1472 }
1227 1473
1228 .history-item-main {1474 .history-item-main {
1229 display: flex;1475 display: flex;
1230- align-items: flex-start;1476+ align-items: center;
1231 justify-content: space-between;1477 justify-content: space-between;
1232- gap: 1rem;1478+ gap: 0.75rem;
1233 }1479 }
1234 1480
1235 .history-title {1481 .history-title {
@@ -1237,34 +1483,35 @@
1237 color: var(--dynamic-text);1483 color: var(--dynamic-text);
1238 white-space: nowrap;1484 white-space: nowrap;
1239 overflow: hidden;1485 overflow: hidden;
1240- flex: 1;
1241- position: relative;
1242- mask-image: linear-gradient(to right, black 70%, transparent 100%);
1243- -webkit-mask-image: linear-gradient(to right, black 70%, transparent 100%);
1244 }1486 }
1245 1487
1488+:global(.history-title.truncated) {
1489+ mask-image: linear-gradient(to right, black 85%, transparent 100%);
1490+ -webkit-mask-image: linear-gradient(to right, black 85%, transparent 100%);
1491+}
1492+
1493+.history-title:hover {
1494+ cursor: pointer;
1495+}
1246 1496
1247 .history-time {1497 .history-time {
1248- font-size: 0.85rem;1498+ font-size: 0.72rem;
1249 color: var(--dynamic-muted);1499 color: var(--dynamic-muted);
1250- flex-shrink: 0;1500+ text-transform: uppercase;
1501+ letter-spacing: 0.08em;
1502+ white-space: nowrap;
1251 }1503 }
1252 1504
1253 .history-url {1505 .history-url {
1254- font-size: 0.8rem;1506+ font-size: 0.72rem;
1255 color: var(--dynamic-muted);1507 color: var(--dynamic-muted);
1256 white-space: nowrap;1508 white-space: nowrap;
1257- font-family:
1258- "JetBrains Mono",
1259- "SFMono-Regular",
1260- Menlo,
1261- monospace;
1262 overflow: hidden;1509 overflow: hidden;
1263- flex: 1;1510+}
1264- min-width: 0;1511+
1265- position: relative;1512+:global(.history-url.truncated) {
1266- mask-image: linear-gradient(to right, black 70%, transparent 100%);1513+ mask-image: linear-gradient(to right, black 85%, transparent 100%);
1267- -webkit-mask-image: linear-gradient(to right, black 70%, transparent 100%);1514+ -webkit-mask-image: linear-gradient(to right, black 85%, transparent 100%);
1268 }1515 }
1269 1516
1270 .history-url :global(.history-url-domain) {1517 .history-url :global(.history-url-domain) {
@@ -1274,364 +1521,313 @@
1274 1521
1275 .history-actions {1522 .history-actions {
1276 display: flex;1523 display: flex;
1277- flex-shrink: 0;1524+ gap: 0.35rem;
1278-}
1279-
1280-.history-pin {
1281- display: flex;
1282- align-items: center;
1283- justify-content: center;
1284- width: 38px;
1285- border-left: 2px solid var(--dynamic-border);
1286- background-color: var(--dynamic-surface);
1287- color: var(--dynamic-muted);
1288- transition: background-color 200ms ease, color 200ms ease;
1289- cursor: pointer;
1290-}
1291-
1292-.history-pin:hover,
1293-.history-pin:focus-visible {
1294- color: var(--dynamic-accent);
1295- background-color: var(--dynamic-bg);
1296- outline: none;
1297 }1525 }
1298 1526
1527+.history-pin,
1299 .history-delete {1528 .history-delete {
1300- display: flex;1529+ display: inline-flex;
1301 align-items: center;1530 align-items: center;
1302 justify-content: center;1531 justify-content: center;
1303- width: 38px;1532+ width: 28px;
1304- border-left: 2px solid var(--dynamic-border);1533+ height: 28px;
1305- background-color: var(--dynamic-surface);1534+ border: 1px solid var(--dynamic-border);
1306 color: var(--dynamic-muted);1535 color: var(--dynamic-muted);
1307- font-size: 1.1rem;1536+ background: transparent;
1308- transition: background-color 200ms ease, color 200ms ease;1537+ transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
1309- flex-shrink: 0;
1310 }1538 }
1311 1539
1540+.history-pin:hover,
1541+.history-pin:focus-visible,
1312 .history-delete:hover,1542 .history-delete:hover,
1313 .history-delete:focus-visible {1543 .history-delete:focus-visible {
1314- color: var(--dynamic-accent);1544+ color: var(--dynamic-text);
1315- background-color: var(--dynamic-bg);1545+ border-color: color-mix(in srgb, var(--dynamic-border) 45%, var(--dynamic-text) 55%);
1546+ background: color-mix(in srgb, var(--dynamic-bg) 80%, var(--dynamic-surface) 20%);
1316 outline: none;1547 outline: none;
1317 }1548 }
1318 1549
1319 .scroll-sentinel {1550 .scroll-sentinel {
1320- width: 100%;
1321 height: 1px;1551 height: 1px;
1322 }1552 }
1323 1553
1324 .loading-more {1554 .loading-more {
1325 padding: 0.75rem;1555 padding: 0.75rem;
1556+ font-size: 0.7rem;
1326 text-align: center;1557 text-align: center;
1327 color: var(--dynamic-muted);1558 color: var(--dynamic-muted);
1328- font-size: 0.85rem;1559+ letter-spacing: 0.08em;
1560+ text-transform: uppercase;
1329 }1561 }
1330 1562
1331 .quick-access-body {1563 .quick-access-body {
1332- gap: 1rem;1564+ gap: 0.9rem;
1333 }1565 }
1334 1566
1335 .quick-access-grid-compact {1567 .quick-access-grid-compact {
1336 display: flex;1568 display: flex;
1337 flex-direction: column;1569 flex-direction: column;
1338- gap: 0.5rem;1570+ gap: 0.75rem;
1339- background-color: var(--dynamic-surface-variant);
1340- border: 2px solid var(--dynamic-border);
1341- padding: 0.5rem;
1342 }1571 }
1343 1572
1344 .quick-access-item-compact {1573 .quick-access-item-compact {
1345- display: flex;1574+ border: 1px solid var(--dynamic-border);
1346- align-items: center;1575+ background: color-mix(in srgb, var(--dynamic-bg) 92%, var(--dynamic-surface) 8%);
1576+ padding: 0.75rem 0.9rem;
1577+ display: grid;
1578+ grid-template-columns: auto 1fr auto;
1347 gap: 0.75rem;1579 gap: 0.75rem;
1348- border-bottom: 1px solid var(--dynamic-border);1580+ align-items: center;
1349- background-color: var(--dynamic-surface-variant);1581+ transition: background-color 150ms ease, border-color 150ms ease;
1350- padding: 0.5rem 0.25rem;
1351 cursor: pointer;1582 cursor: pointer;
1352- transition: background-color 200ms ease;
1353-}
1354-
1355-.quick-access-item-compact:last-child {
1356- border-bottom: none;
1357 }1583 }
1358 1584
1359 .quick-access-item-compact:hover,1585 .quick-access-item-compact:hover,
1360 .quick-access-item-compact:focus-visible {1586 .quick-access-item-compact:focus-visible {
1361- background-color: var(--dynamic-surface);1587+ border-color: color-mix(in srgb, var(--dynamic-border) 45%, var(--dynamic-text) 55%);
1588+ background: color-mix(in srgb, var(--dynamic-bg) 70%, var(--dynamic-surface) 30%);
1362 outline: none;1589 outline: none;
1363 }1590 }
1364 1591
1365 .quick-access-favicon-compact {1592 .quick-access-favicon-compact {
1366- width: 32px;1593+ width: 36px;
1367- height: 32px;1594+ height: 36px;
1368- border: 2px solid var(--dynamic-border);1595+ border: 1px solid var(--dynamic-border);
1369- background-color: var(--dynamic-surface-variant);
1370 display: flex;1596 display: flex;
1371 align-items: center;1597 align-items: center;
1372 justify-content: center;1598 justify-content: center;
1373- flex-shrink: 0;1599+ background: var(--dynamic-bg);
1374- border-radius: 0;
1375 }1600 }
1376 1601
1377 .quick-access-favicon-img-compact {1602 .quick-access-favicon-img-compact {
1378- width: 70%;1603+ width: 60%;
1379- height: 70%;1604+ height: 60%;
1380 object-fit: contain;1605 object-fit: contain;
1381 }1606 }
1382 1607
1383 .quick-access-fallback-compact {1608 .quick-access-fallback-compact {
1384- width: 100%;
1385- height: 100%;
1386 display: flex;1609 display: flex;
1387 align-items: center;1610 align-items: center;
1388 justify-content: center;1611 justify-content: center;
1612+ width: 100%;
1613+ height: 100%;
1389 color: var(--dynamic-muted);1614 color: var(--dynamic-muted);
1390 }1615 }
1391 1616
1617+.quick-access-fallback-compact svg {
1618+ opacity: 0.55;
1619+}
1620+
1392 .quick-access-meta-compact {1621 .quick-access-meta-compact {
1393- flex: 1;
1394- min-width: 0;
1395 display: flex;1622 display: flex;
1396 flex-direction: column;1623 flex-direction: column;
1397- gap: 0.125rem;1624+ gap: 0.2rem;
1625+ min-width: 0;
1398 }1626 }
1399 1627
1400 .quick-access-title-compact {1628 .quick-access-title-compact {
1401- font-size: 0.95rem;
1402- font-weight: 600;
1403 color: var(--dynamic-text);1629 color: var(--dynamic-text);
1630+ font-weight: 600;
1404 white-space: nowrap;1631 white-space: nowrap;
1405 overflow: hidden;1632 overflow: hidden;
1406- position: relative;1633+}
1407- mask-image: linear-gradient(to right, black 70%, transparent 100%);1634+
1408- -webkit-mask-image: linear-gradient(to right, black 70%, transparent 100%);1635+:global(.quick-access-title-compact.truncated) {
1636+ mask-image: linear-gradient(to right, black 85%, transparent 100%);
1637+ -webkit-mask-image: linear-gradient(to right, black 85%, transparent 100%);
1638+}
1639+
1640+.quick-access-title-compact:hover {
1641+ cursor: pointer;
1409 }1642 }
1410 1643
1411 .quick-access-domain-compact {1644 .quick-access-domain-compact {
1412- font-size: 0.8rem;
1413 color: var(--dynamic-muted);1645 color: var(--dynamic-muted);
1414- white-space: nowrap;1646+ font-size: 0.72rem;
1415- overflow: hidden;1647+ text-transform: uppercase;
1416- text-overflow: ellipsis;1648+ letter-spacing: 0.08em;
1417 }1649 }
1418 1650
1419 .quick-access-actions-compact {1651 .quick-access-actions-compact {
1420 display: flex;1652 display: flex;
1421- align-items: center;1653+ flex-direction: column;
1422- gap: 0.5rem;1654+ gap: 0.3rem;
1423- flex-shrink: 0;1655+ align-items: flex-end;
1656+ justify-content: center;
1424 }1657 }
1425 1658
1426 .quick-access-pin-compact {1659 .quick-access-pin-compact {
1427- display: flex;1660+ display: inline-flex;
1428 align-items: center;1661 align-items: center;
1429 justify-content: center;1662 justify-content: center;
1430- width: 24px;1663+ width: 26px;
1431- height: 24px;1664+ height: 26px;
1432 border: 1px solid var(--dynamic-border);1665 border: 1px solid var(--dynamic-border);
1433- background-color: var(--dynamic-surface-variant);
1434 color: var(--dynamic-muted);1666 color: var(--dynamic-muted);
1435- transition: background-color 200ms ease, color 200ms ease;1667+ background: transparent;
1668+ transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
1436 cursor: pointer;1669 cursor: pointer;
1437- border-radius: 0;
1438 }1670 }
1439 1671
1440 .quick-access-pin-compact:hover,1672 .quick-access-pin-compact:hover,
1441 .quick-access-pin-compact:focus-visible {1673 .quick-access-pin-compact:focus-visible {
1442- color: var(--dynamic-accent);1674+ color: var(--dynamic-text);
1443- background-color: var(--dynamic-surface);1675+ border-color: color-mix(in srgb, var(--dynamic-border) 45%, var(--dynamic-text) 55%);
1676+ background: color-mix(in srgb, var(--dynamic-bg) 80%, var(--dynamic-surface) 20%);
1444 outline: none;1677 outline: none;
1445 }1678 }
1446 1679
1447-.quick-access-visits-compact {1680+.quick-access-pin-compact svg {
1448- font-size: 0.75rem;1681+ width: 14px;
1449- color: var(--dynamic-accent);1682+ height: 14px;
1450- text-transform: uppercase;
1451- letter-spacing: 0.05em;
1452- font-weight: 600;
1453- flex-shrink: 0;
1454 }1683 }
1455 1684
1456-1685+.quick-access-visits-compact {
1457-.stat-value {1686+ font-size: 0.7rem;
1458- font-size: 1.4rem;1687+ color: var(--dynamic-muted);
1459- font-weight: 600;1688+ text-transform: uppercase;
1460- color: var(--dynamic-text);1689+ letter-spacing: 0.08em;
1461 }1690 }
1462 1691
1463-.stat-label {1692+.show-more-button {
1464- font-size: 0.8rem;1693+ width: 100%;
1694+ padding: 0.65rem 0.75rem;
1695+ border: 1px solid var(--dynamic-border);
1696+ background: transparent;
1465 color: var(--dynamic-muted);1697 color: var(--dynamic-muted);
1698+ font-size: 0.72rem;
1466 text-transform: uppercase;1699 text-transform: uppercase;
1467 letter-spacing: 0.08em;1700 letter-spacing: 0.08em;
1701+ cursor: pointer;
1702+ transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
1703+ border-radius: 0;
1704+}
1705+
1706+.show-more-button:hover,
1707+.show-more-button:focus-visible {
1708+ background: color-mix(in srgb, var(--dynamic-bg) 75%, var(--dynamic-surface) 25%);
1709+ color: var(--dynamic-text);
1710+ border-color: color-mix(in srgb, var(--dynamic-border) 45%, var(--dynamic-text) 55%);
1711+ outline: none;
1468 }1712 }
1469 1713
1470 .stats-grid-horizontal {1714 .stats-grid-horizontal {
1471- display: flex;1715+ display: grid;
1472- flex-wrap: wrap;1716+ gap: 0.85rem;
1473- gap: 1rem;1717+ grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
1474- justify-content: space-between;
1475 }1718 }
1476 1719
1477 .stat-item-horizontal {1720 .stat-item-horizontal {
1478- flex: 1;1721+ border: 1px solid var(--dynamic-border);
1479- min-width: 120px;1722+ padding: 0.85rem;
1480- border: 2px solid var(--dynamic-border);
1481- background-color: var(--dynamic-surface-variant);
1482- padding: 0.75rem;
1483 display: flex;1723 display: flex;
1484 flex-direction: column;1724 flex-direction: column;
1485- gap: 0.25rem;1725+ gap: 0.4rem;
1486- text-align: center;1726+ background: color-mix(in srgb, var(--dynamic-bg) 92%, var(--dynamic-surface) 8%);
1487- border-radius: 0;1727+ text-transform: uppercase;
1728+ letter-spacing: 0.08em;
1729+}
1730+
1731+.stat-value {
1732+ font-size: 0.95rem;
1733+ color: var(--dynamic-text);
1734+ font-weight: 600;
1488 }1735 }
1489 1736
1490-.shortcuts-panel {1737+.stat-label {
1491- gap: 0;1738+ font-size: 0.68rem;
1739+ color: var(--dynamic-muted);
1492 }1740 }
1493 1741
1494 .shortcuts-list {1742 .shortcuts-list {
1495- display: flex;1743+ display: grid;
1496- flex-wrap: wrap;1744+ gap: 0.6rem;
1497- gap: 0.85rem;
1498 }1745 }
1499 1746
1500 .shortcut-item {1747 .shortcut-item {
1501- display: flex;1748+ display: grid;
1749+ grid-template-columns: auto 1fr;
1750+ gap: 0.6rem;
1502 align-items: center;1751 align-items: center;
1503- gap: 0.75rem;1752+ border: 1px solid var(--dynamic-border);
1504- border: 2px solid var(--dynamic-border);1753+ padding: 0.6rem 0.75rem;
1505- background-color: var(--dynamic-bg);1754+ background: color-mix(in srgb, var(--dynamic-bg) 92%, var(--dynamic-surface) 8%);
1506- padding: 0.75rem 1rem;
1507- border-radius: 0;
1508 }1755 }
1509 1756
1510 .shortcut-key-badge {1757 .shortcut-key-badge {
1511- font-family:1758+ font-size: 0.72rem;
1512- "JetBrains Mono",
1513- "SFMono-Regular",
1514- Menlo,
1515- monospace;
1516- font-size: 0.85rem;
1517 text-transform: uppercase;1759 text-transform: uppercase;
1518 letter-spacing: 0.08em;1760 letter-spacing: 0.08em;
1519- padding: 0.35rem 0.65rem;1761+ padding: 0.25rem 0.6rem;
1520- border: 2px solid var(--dynamic-border);1762+ border: 1px solid var(--dynamic-border);
1521- background-color: var(--dynamic-surface-variant);
1522- color: var(--dynamic-muted);
1523- font-weight: 500;
1524- border-radius: 0;
1525-}
1526-
1527-.shortcut-desc {
1528- font-size: 0.95rem;
1529 color: var(--dynamic-text);1763 color: var(--dynamic-text);
1764+ background: color-mix(in srgb, var(--dynamic-bg) 80%, var(--dynamic-surface) 20%);
1530 }1765 }
1531 1766
1532-.shortcuts-panel .loading {1767+.shortcut-desc {
1533- border-style: solid;1768+ font-size: 0.72rem;
1769+ color: var(--dynamic-muted);
1770+ letter-spacing: 0.06em;
1534 }1771 }
1535 1772
1536-/* Responsive Design */1773+@media (max-width: 960px) {
1537-@media (max-width: 1200px) {1774+ .terminal-body {
1538- .history-panel,1775+ padding: 1.1rem;
1539- .quick-access-panel {
1540- min-width: min(28rem, 100%);
1541 }1776 }
1542-}
1543 1777
1544-@media (max-width: 960px) {1778+ .terminal-grid {
1545- .homepage-shell {1779+ gap: 0.75rem;
1546- padding: clamp(1.25rem, 5vw, 2rem);
1547 }1780 }
1548 1781
1549 .main-panels {1782 .main-panels {
1550- flex-direction: column;1783+ grid-template-columns: 1fr;
1551 }1784 }
1552 1785
1553- .history-panel,1786+ .last-visit-banner {
1554- .quick-access-panel {1787+ grid-template-columns: minmax(0, auto) minmax(0, 1fr);
1555- min-width: 100%;1788+ grid-template-rows: repeat(3, auto);
1556- max-width: 100%;1789+ gap: 0.5rem 0.75rem;
1557- width: 100%;
1558 }1790 }
1559 1791
1792+ .banner-time,
1793+ .banner-absolute {
1794+ justify-self: flex-start;
1795+ }
1560 }1796 }
1561 1797
1562 @media (max-width: 640px) {1798 @media (max-width: 640px) {
1563- .theme-toggle-button {1799+ .homepage-shell {
1564- width: 2.75rem;1800+ padding: 1.25rem;
1565- height: 2.75rem;
1566- }
1567-
1568- .panel-body,
1569- .panel-header {
1570- padding-left: 1.25rem;
1571- padding-right: 1.25rem;
1572 }1801 }
1573 1802
1574-1803+ .terminal-header {
1575- .history-item {
1576 flex-direction: column;1804 flex-direction: column;
1577 align-items: flex-start;1805 align-items: flex-start;
1578 }1806 }
1579 1807
1580- .history-actions {1808+ .theme-toggle-button {
1581- width: 100%;1809+ align-self: flex-end;
1582- border-top: 2px solid var(--dynamic-border);
1583 }1810 }
1584 1811
1585- .history-pin,1812+ .terminal-status-row {
1586- .history-delete {1813+ gap: 0.5rem;
1587- flex: 1;
1588- border-left: 0;
1589 }1814 }
1590 1815
1591- .history-pin {1816+ .status-chip {
1592- border-right: 1px solid var(--dynamic-border);1817+ padding: 0.35rem 0.65rem;
1593 }1818 }
1594 1819
1595- .history-item-main {1820+ .last-visit-banner {
1596- flex-direction: column;1821+ grid-template-columns: minmax(0, 1fr);
1597- align-items: flex-start;1822+ grid-template-rows: repeat(4, auto);
1598- gap: 0.35rem;
1599 }1823 }
1600 1824
1601- .history-time {1825+ .banner-label,
1602- order: 3;1826+ .banner-title,
1827+ .banner-domain,
1828+ .banner-time,
1829+ .banner-absolute {
1830+ justify-self: flex-start;
1603 }1831 }
1604-
1605- .stats-grid-horizontal {
1606- flex-direction: column;
1607- gap: 0.75rem;
1608- }
1609-
1610- .stat-item-horizontal {
1611- min-width: 100%;
1612- }
1613-}
1614-
1615-.show-more-button {
1616- width: 100%;
1617- padding: 0.75rem 1rem;
1618- border: 2px solid var(--dynamic-border);
1619- background-color: var(--dynamic-surface-variant);
1620- color: var(--dynamic-text);
1621- font-size: 0.9rem;
1622- font-weight: 500;
1623- cursor: pointer;
1624- transition:
1625- background-color 200ms ease,
1626- border-color 200ms ease;
1627- border-radius: 0;
1628- margin-top: 0.5rem;
1629-}
1630-
1631-.show-more-button:hover,
1632-.show-more-button:focus-visible {
1633- background-color: var(--dynamic-surface);
1634- border-color: var(--dynamic-accent);
1635- outline: none;
1636 }1832 }
1637 </style>1833 </style>

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close