CoolFace
Apppublic

Group-1-5010/NotebookLM

sourceHugging Facemitupdated 7mo agoView on Hugging Face
1likes
theme.py395 linesDownload Raw Back to root
1"""Dark theme, custom CSS, and logo SVGs for the NotebookLM Gradio app."""2 3import base644import gradio as gr5 6# ── Logo SVGs ────────────────────────────────────────────────────────────────7 8LOGO_SVG = """<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 280 60">9  <defs>10    <linearGradient id="lg1" x1="0%" y1="0%" x2="100%" y2="100%">11      <stop offset="0%" style="stop-color:#667eea"/>12      <stop offset="100%" style="stop-color:#764ba2"/>13    </linearGradient>14    <linearGradient id="lg2" x1="0%" y1="0%" x2="100%" y2="100%">15      <stop offset="0%" style="stop-color:#a78bfa"/>16      <stop offset="100%" style="stop-color:#667eea"/>17    </linearGradient>18    <linearGradient id="sp" x1="0%" y1="0%" x2="100%" y2="100%">19      <stop offset="0%" style="stop-color:#fbbf24"/>20      <stop offset="100%" style="stop-color:#f59e0b"/>21    </linearGradient>22  </defs>23  <g transform="translate(4,6)">24    <rect x="2" y="4" width="36" height="44" rx="4" fill="url(#lg1)"/>25    <rect x="2" y="4" width="8" height="44" rx="3" fill="url(#lg2)" opacity="0.7"/>26    <line x1="16" y1="16" x2="32" y2="16" stroke="rgba(255,255,255,0.5)" stroke-width="1.8" stroke-linecap="round"/>27    <line x1="16" y1="23" x2="30" y2="23" stroke="rgba(255,255,255,0.4)" stroke-width="1.8" stroke-linecap="round"/>28    <line x1="16" y1="30" x2="32" y2="30" stroke="rgba(255,255,255,0.5)" stroke-width="1.8" stroke-linecap="round"/>29    <line x1="16" y1="37" x2="28" y2="37" stroke="rgba(255,255,255,0.4)" stroke-width="1.8" stroke-linecap="round"/>30    <g transform="translate(32,2)">31      <path d="M6 0 L7.5 4.5 L12 6 L7.5 7.5 L6 12 L4.5 7.5 L0 6 L4.5 4.5 Z" fill="url(#sp)"/>32      <path d="M14 8 L14.8 10.2 L17 11 L14.8 11.8 L14 14 L13.2 11.8 L11 11 L13.2 10.2 Z" fill="#fbbf24" opacity="0.7"/>33    </g>34  </g>35  <text x="56" y="28" font-family="Inter,-apple-system,sans-serif" font-size="22" font-weight="700">36    <tspan fill="url(#lg1)">Notebook</tspan><tspan fill="#a78bfa" font-weight="800">LM</tspan>37  </text>38  <text x="57" y="46" font-family="Inter,-apple-system,sans-serif" font-size="10.5" fill="#8888aa" font-weight="400" letter-spacing="0.8">39    AI-Powered Study Companion40  </text>41</svg>"""42 43LOGO_ICON_SVG = """<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 60">44  <defs>45    <linearGradient id="ig1" x1="0%" y1="0%" x2="100%" y2="100%">46      <stop offset="0%" style="stop-color:#667eea"/>47      <stop offset="100%" style="stop-color:#764ba2"/>48    </linearGradient>49    <linearGradient id="ig2" x1="0%" y1="0%" x2="100%" y2="100%">50      <stop offset="0%" style="stop-color:#a78bfa"/>51      <stop offset="100%" style="stop-color:#667eea"/>52    </linearGradient>53    <linearGradient id="isp" x1="0%" y1="0%" x2="100%" y2="100%">54      <stop offset="0%" style="stop-color:#fbbf24"/>55      <stop offset="100%" style="stop-color:#f59e0b"/>56    </linearGradient>57  </defs>58  <g transform="translate(2,4)">59    <rect x="2" y="4" width="36" height="44" rx="5" fill="url(#ig1)"/>60    <rect x="2" y="4" width="9" height="44" rx="4" fill="url(#ig2)" opacity="0.7"/>61    <line x1="16" y1="16" x2="32" y2="16" stroke="rgba(255,255,255,0.55)" stroke-width="2" stroke-linecap="round"/>62    <line x1="16" y1="23" x2="30" y2="23" stroke="rgba(255,255,255,0.4)" stroke-width="2" stroke-linecap="round"/>63    <line x1="16" y1="30" x2="32" y2="30" stroke="rgba(255,255,255,0.55)" stroke-width="2" stroke-linecap="round"/>64    <line x1="16" y1="37" x2="28" y2="37" stroke="rgba(255,255,255,0.4)" stroke-width="2" stroke-linecap="round"/>65    <g transform="translate(30,0)">66      <path d="M7 0 L8.8 5.3 L14 7 L8.8 8.8 L7 14 L5.2 8.8 L0 7 L5.2 5.3 Z" fill="url(#isp)"/>67      <path d="M16 9 L17 11.5 L19.5 12.5 L17 13.5 L16 16 L15 13.5 L12.5 12.5 L15 11.5 Z" fill="#fbbf24" opacity="0.7"/>68    </g>69  </g>70</svg>"""71 72 73def get_logo_b64(svg_str: str) -> str:74    return base64.b64encode(svg_str.encode()).decode()75 76 77LOGO_B64 = get_logo_b64(LOGO_SVG)78ICON_B64 = get_logo_b64(LOGO_ICON_SVG)79 80# ── Gradio Dark Theme ────────────────────────────────────────────────────────81 82dark_theme = gr.themes.Base(83    primary_hue=gr.themes.colors.indigo,84    secondary_hue=gr.themes.colors.purple,85    neutral_hue=gr.themes.colors.slate,86    font=gr.themes.GoogleFont("Inter"),87).set(88    body_background_fill="#0e1117",89    body_background_fill_dark="#0e1117",90    block_background_fill="rgba(255,255,255,0.02)",91    block_background_fill_dark="rgba(255,255,255,0.02)",92    block_border_color="rgba(255,255,255,0.08)",93    block_border_color_dark="rgba(255,255,255,0.08)",94    block_label_text_color="#a0a0b8",95    block_label_text_color_dark="#a0a0b8",96    block_title_text_color="#e0e0f0",97    block_title_text_color_dark="#e0e0f0",98    body_text_color="#c8c8d8",99    body_text_color_dark="#c8c8d8",100    button_primary_background_fill="linear-gradient(135deg, #667eea 0%, #764ba2 100%)",101    button_primary_background_fill_dark="linear-gradient(135deg, #667eea 0%, #764ba2 100%)",102    button_primary_text_color="white",103    button_primary_text_color_dark="white",104    button_secondary_background_fill="rgba(255,255,255,0.04)",105    button_secondary_background_fill_dark="rgba(255,255,255,0.04)",106    button_secondary_border_color="rgba(255,255,255,0.12)",107    button_secondary_border_color_dark="rgba(255,255,255,0.12)",108    button_secondary_text_color="#d0d0e0",109    button_secondary_text_color_dark="#d0d0e0",110    border_color_primary="rgba(255,255,255,0.08)",111    border_color_primary_dark="rgba(255,255,255,0.08)",112    input_background_fill="rgba(255,255,255,0.03)",113    input_background_fill_dark="rgba(255,255,255,0.03)",114    input_border_color="rgba(255,255,255,0.1)",115    input_border_color_dark="rgba(255,255,255,0.1)",116    shadow_drop="none",117    shadow_drop_lg="none",118    shadow_spread="none",119)120 121# ── Custom CSS ───────────────────────────────────────────────────────────────122 123CUSTOM_CSS = """124/* ── Import Google Font ── */125@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');126 127/* ── Sidebar ── */128#sidebar {129    background: linear-gradient(180deg, #1a1a2e 0%, #16213e 100%) !important;130    border-right: 1px solid rgba(255,255,255,0.06);131    padding: 16px !important;132    min-height: 100vh;133    position: sticky;134    top: 0;135    align-self: flex-start;136    max-height: 100vh;137    overflow-y: auto;138    border-radius: 0 !important;139}140#sidebar .gr-button-primary {141    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;142    border: none !important;143    border-radius: 10px !important;144}145#sidebar .gr-button-secondary {146    background: rgba(255,255,255,0.05) !important;147    border: 1px solid rgba(255,255,255,0.1) !important;148    border-radius: 10px !important;149    color: #d0d0e0 !important;150}151 152/* ── Notebook selector radio ── */153#notebook-selector label {154    border-radius: 10px !important;155    padding: 8px 14px !important;156    transition: all 0.2s ease !important;157    font-size: 0.85rem !important;158}159#notebook-selector label.selected {160    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;161    color: white !important;162}163 164/* ── Tab styling ── */165.tabs > .tab-nav > button {166    border-radius: 10px !important;167    padding: 10px 24px !important;168    font-weight: 500 !important;169    font-size: 0.9rem !important;170}171.tabs > .tab-nav > button.selected {172    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;173    color: white !important;174}175 176/* ── Chat ── */177#chatbot {178    border-radius: 14px !important;179    border: 1px solid rgba(255,255,255,0.08) !important;180}181#chatbot .message {182    border-radius: 14px !important;183    padding: 14px 18px !important;184}185/* User bubble — shrink to fit content */186#chatbot .bot-row { justify-content: flex-start !important; }187#chatbot .user-row { justify-content: flex-end !important; }188#chatbot .user-row .message-bubble-border {189    max-width: fit-content !important;190}191#chatbot .message.user {192    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;193    color: white !important;194    border: none !important;195    box-shadow: 0 4px 14px rgba(102,126,234,0.25);196    max-width: fit-content !important;197}198/* Assistant bubble */199#chatbot .message.bot {200    background: rgba(40, 44, 66, 0.85) !important;201    border: 1px solid rgba(102, 126, 234, 0.3) !important;202    color: #c8c8d8 !important;203    box-shadow: 0 4px 12px rgba(102, 126, 234, 0.25);204    border-radius: 14px !important;205    padding: 14px 18px !important;206    backdrop-filter: blur(6px);207}208 209/* ── Cards ── */210.source-card {211    display: flex;212    align-items: center;213    gap: 16px;214    padding: 16px 20px;215    background: rgba(255,255,255,0.02);216    border: 1px solid rgba(255,255,255,0.08);217    border-radius: 14px;218    margin-bottom: 10px;219    transition: all 0.2s ease;220}221.source-card:hover {222    border-color: rgba(102,126,234,0.3);223    background: rgba(255,255,255,0.04);224}225.source-icon {226    width: 48px; height: 48px; border-radius: 12px;227    display: flex; align-items: center; justify-content: center;228    font-size: 1.5rem; flex-shrink: 0;229}230.source-icon.pdf { background: rgba(239,68,68,0.15); }231.source-icon.pptx { background: rgba(249,115,22,0.15); }232.source-icon.txt { background: rgba(59,130,246,0.15); }233.source-icon.url { background: rgba(34,197,94,0.15); }234.source-icon.youtube { background: rgba(239,68,68,0.15); }235.source-info { flex: 1; min-width: 0; }236.source-info .name {237    font-weight: 600; font-size: 0.95rem; color: #e0e0f0;238    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;239}240.source-info .meta { font-size: 0.8rem; color: #707088; margin-top: 2px; }241.source-badge {242    padding: 4px 12px; border-radius: 20px; font-size: 0.75rem;243    font-weight: 600; letter-spacing: 0.3px;244}245.source-badge.ready { background: rgba(34,197,94,0.15); color: #22c55e; }246.source-badge.processing {247    background: rgba(234,179,8,0.15); color: #eab308;248    animation: pulse-badge 1.5s ease-in-out infinite;249}250.source-badge.failed { background: rgba(239,68,68,0.15); color: #ef4444; cursor: help; }251@keyframes pulse-badge {252    0%, 100% { opacity: 1; }253    50% { opacity: 0.5; }254}255 256/* ── Welcome hero ── */257.welcome-hero {258    text-align: center; padding: 80px 40px;259    background: linear-gradient(135deg, rgba(102,126,234,0.08) 0%, rgba(118,75,162,0.08) 100%);260    border-radius: 20px; border: 1px solid rgba(102,126,234,0.15); margin: 20px 0;261}262.welcome-hero h1 {263    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);264    -webkit-background-clip: text; -webkit-text-fill-color: transparent;265    font-size: 2.5rem; font-weight: 700; margin-bottom: 12px;266}267.welcome-hero p { color: #9090a8; font-size: 1.1rem; line-height: 1.6; }268 269/* ── Empty state ── */270.empty-state {271    text-align: center; padding: 60px 30px; color: #707088;272}273.empty-state h3 { color: #a0a0b8; margin-bottom: 8px; font-weight: 600; }274.empty-state p { font-size: 0.95rem; line-height: 1.5; }275 276/* ── Notebook header ── */277.notebook-header {278    padding: 0 0 16px 0; margin-bottom: 16px;279    border-bottom: 1px solid rgba(255,255,255,0.06);280}281.notebook-header h2 {282    font-weight: 700; font-size: 1.5rem; margin: 0; color: #e8e8f8;283}284.notebook-header .meta { font-size: 0.85rem; color: #707088; margin-top: 4px; }285 286/* ── Citation chip ── */287.citation-chip {288    display: inline-flex; align-items: center; gap: 6px;289    padding: 6px 14px; background: rgba(102,126,234,0.1);290    border: 1px solid rgba(102,126,234,0.2); border-radius: 20px;291    font-size: 0.8rem; color: #a0b0f0; margin: 3px 4px;292}293 294/* ── Artifact section header ── */295.artifact-section-header {296    display: flex; align-items: center; gap: 10px; margin-bottom: 12px;297}298.artifact-section-icon {299    width: 36px; height: 36px; border-radius: 10px;300    display: flex; align-items: center; justify-content: center; font-size: 1.1rem;301}302 303/* ── Locked state ── */304.locked-state {305    text-align: center; padding: 50px 30px;306    background: rgba(255,255,255,0.02);307    border: 1px solid rgba(255,255,255,0.06);308    border-radius: 16px;309}310 311/* ── File uploader ── */312.gr-file-upload {313    border-radius: 14px !important;314    border: 2px dashed rgba(102,126,234,0.3) !important;315    background: rgba(102,126,234,0.03) !important;316}317 318/* ── Primary button ── */319.gr-button-primary {320    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;321    border: none !important; border-radius: 10px !important;322    font-weight: 600 !important;323}324.gr-button-primary:hover {325    opacity: 0.9 !important;326    transform: translateY(-1px) !important;327    box-shadow: 0 4px 15px rgba(102,126,234,0.3) !important;328}329 330/* ── Source delete dropdown ── */331#source-delete-dropdown {332    border: 1px solid rgba(102,126,234,0.3);333    border-radius: 12px;334    background: rgba(102,126,234,0.06);335}336#source-delete-dropdown label {337    color: #a0a0f0 !important;338    font-weight: 600;339}340#source-delete-dropdown input, #source-delete-dropdown .wrap {341    background: rgba(14,17,23,0.8) !important;342    border-color: rgba(102,126,234,0.25) !important;343    color: #e0e0f0 !important;344    border-radius: 10px !important;345}346#source-delete-dropdown ul {347    background: #1a1d2e !important;348    border: 1px solid rgba(102,126,234,0.3) !important;349    border-radius: 10px !important;350}351#source-delete-dropdown li {352    color: #c0c0e0 !important;353}354#source-delete-dropdown li:hover, #source-delete-dropdown li.selected {355    background: rgba(102,126,234,0.15) !important;356    color: #e0e0f0 !important;357}358 359/* ── Scrollbar ── */360::-webkit-scrollbar { width: 6px; }361::-webkit-scrollbar-track { background: transparent; }362::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 3px; }363::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.25); }364 365/* ── Hide Gradio footer ── */366footer { display: none !important; }367 368/* ── Auth gate ── */369#auth-gate { max-width: 500px; margin: 100px auto; }370"""371 372# ── Reusable HTML Templates ──────────────────────────────────────────────────373 374WELCOME_HTML = f"""375<div class="welcome-hero">376    <img src="data:image/svg+xml;base64,{ICON_B64}" style="width:64px; margin-bottom:16px;" />377    <h1>NotebookLM</h1>378    <p>Your AI-powered study companion.<br>379    Sign in with your Hugging Face account to get started.</p>380</div>381"""382 383NO_NOTEBOOKS_HTML = """384<div class="welcome-hero">385    <h1>NotebookLM</h1>386    <p>Create a notebook from the sidebar to get started.</p>387</div>388"""389 390SIDEBAR_LOGO_HTML = f"""391<div style="padding: 8px 0 4px 0;">392    <img src="data:image/svg+xml;base64,{LOGO_B64}" style="width:100%; max-width:240px;" />393</div>394"""395