Chandra

 view release on metacpan or  search on metacpan

lib/Chandra/Theme.pm  view on Meta::CPAN

}

a { color: var(--chandra-primary); text-decoration: none; }
a:hover { text-decoration: underline; }

code, pre, kbd {
    font-family: var(--chandra-font-mono);
    font-size: 0.9em;
}

pre {
    background: var(--chandra-surface);
    border: 1px solid var(--chandra-border);
    border-radius: var(--chandra-radius);
    padding: 12px 16px;
    overflow-x: auto;
}

code {
    background: var(--chandra-surface);
    padding: 2px 6px;
    border-radius: 3px;
}

pre code { background: none; padding: 0; }

hr {
    border: none;
    border-top: 1px solid var(--chandra-border);
    margin: 16px 0;
}

h1, h2, h3, h4, h5, h6 {
    margin: 24px 0 8px;
    line-height: 1.25;
}

h1 { font-size: 2em; }
h2 { font-size: 1.5em; }
h3 { font-size: 1.25em; }

CSS
}

sub _component_css {
    return <<'CSS';

/* ── Buttons ──────────────────────────────────────────── */

button, .chandra-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 16px;
    border: 1px solid var(--chandra-border);
    border-radius: var(--chandra-radius);
    background: var(--chandra-surface);
    color: var(--chandra-text);
    font-family: inherit;
    font-size: inherit;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}
button:hover, .chandra-btn:hover { background: var(--chandra-hover); }
button:disabled { opacity: 0.5; cursor: not-allowed; }

.chandra-btn-primary {
    background: var(--chandra-primary);
    color: #fff;
    border-color: var(--chandra-primary);
}
.chandra-btn-primary:hover { opacity: 0.9; }

.chandra-btn-danger {
    background: var(--chandra-danger);
    color: #fff;
    border-color: var(--chandra-danger);
}

.chandra-btn-secondary {
    background: transparent;
    border-color: var(--chandra-border);
}

/* ── Inputs ───────────────────────────────────────────── */

input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="search"], input[type="url"],
input[type="tel"], input[type="date"], input[type="time"],
textarea, select {
    padding: 6px 10px;
    border: 1px solid var(--chandra-input-border);
    border-radius: var(--chandra-radius);
    background: var(--chandra-input-bg);
    color: var(--chandra-text);
    font-family: inherit;
    font-size: inherit;
    transition: border-color 0.15s, box-shadow 0.15s;
}
input:focus, textarea:focus, select:focus {
    outline: none;
    border-color: var(--chandra-primary);
    box-shadow: 0 0 0 2px rgba(33, 150, 243, 0.2);
}

/* ── Form fields (Chandra::Form) ──────────────────────── */

.chandra-form { display: flex; flex-direction: column; gap: 12px; }
.chandra-field { display: flex; flex-direction: column; gap: 4px; }
.chandra-label { font-weight: 500; font-size: 0.9em; color: var(--chandra-text-muted); }
.chandra-submit {
    align-self: flex-start;
    padding: 8px 24px;
    background: var(--chandra-primary);
    color: #fff;
    border: none;
    border-radius: var(--chandra-radius);
    cursor: pointer;
    font-weight: 500;
}
.chandra-submit:hover { opacity: 0.9; }
.chandra-error { color: var(--chandra-danger); font-size: 0.85em; }
.chandra-group { border: 1px solid var(--chandra-border); border-radius: var(--chandra-radius); padding: 12px; }
.chandra-group legend { font-weight: 600; padding: 0 6px; }

/* ── Table (Chandra::Table) ───────────────────────────── */

.chandra-table-wrap { font-family: inherit; }
.chandra-table { width: 100%; border-collapse: collapse; }
.chandra-table th, .chandra-table td {
    padding: 8px 12px;
    text-align: left;
    border-bottom: 1px solid var(--chandra-border);
}
.chandra-table th {
    background: var(--chandra-surface);
    font-weight: 600;
    user-select: none;
}
.chandra-table-sortable { cursor: pointer; }
.chandra-table-sortable:hover { background: var(--chandra-hover); }
.chandra-table-stripe { background: var(--chandra-surface); }
.chandra-table-selected { background: var(--chandra-selected) !important; }
.chandra-table-select { width: 40px; text-align: center; }
.chandra-table-empty, .chandra-table-loading {
    text-align: center;
    padding: 24px;
    color: var(--chandra-text-muted);
}
.chandra-table-filters { padding: 8px 0; display: flex; gap: 8px; flex-wrap: wrap; }
.chandra-table-filter { font-size: 0.9em; }
.chandra-table-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 12px 0;
}
.chandra-table-page-btn {
    padding: 4px 10px;
    font-size: 0.85em;
}
.chandra-table-page-active {
    background: var(--chandra-primary) !important;
    color: #fff;
    border-color: var(--chandra-primary);
}
.chandra-table-info { margin-right: 12px; font-size: 0.85em; color: var(--chandra-text-muted); }

/* ── Context menu ─────────────────────────────────────── */

.chandra-context-menu {
    background: var(--chandra-bg);
    border: 1px solid var(--chandra-border);
    border-radius: var(--chandra-radius);
    box-shadow: var(--chandra-shadow);
    padding: 4px 0;
    min-width: 180px;
}
.chandra-context-menu-item {
    padding: 6px 16px;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
}
.chandra-context-menu-item:hover { background: var(--chandra-hover); }

/* ── Scrollbar (webkit) ───────────────────────────────── */

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
    background: var(--chandra-border);
    border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover { background: var(--chandra-text-muted); }

CSS
}

1;

__END__

=head1 NAME

Chandra::Theme - CSS theme system for Chandra apps

=head1 SYNOPSIS

    use Chandra::App;
    use Chandra::Theme;

    my $app = Chandra::App->new(title => 'My App');

    # Built-in themes
    Chandra::Theme->apply($app, 'dark');
    Chandra::Theme->apply($app, 'light');

    # Auto-detect OS preference
    Chandra::Theme->apply($app, 'auto');

    # Custom theme (merged with light as base)
    Chandra::Theme->apply($app, {
        primary => '#6200ea',
        bg      => '#fafafa',
        surface => '#ffffff',
        radius  => '12px',
    });

    $app->run;

=head1 DESCRIPTION

C<Chandra::Theme> provides a CSS theme system using CSS custom properties.
It includes built-in light and dark themes, styles for all Chandra
components (Form, Table, ContextMenu), and base typography/reset styles.

=head1 CSS CUSTOM PROPERTIES

All tokens are available as C<--chandra-*> CSS variables:



( run in 0.815 second using v1.01-cache-2.11-cpan-140bd7fdf52 )