MDC

Bottom Sheet

Demo

Cancelable

Code
<mdc-bottom-sheet id="bs-cancelable-true" variant="modal" cancelable>
    <h2 style="margin: 0 0 8px 0; font: var(--mdc-typescale-title-medium);">Cancelable (true)</h2>
    <p>Esc and outside-tap (scrim) dismiss the sheet.</p>
</mdc-bottom-sheet>

<mdc-bottom-sheet id="bs-cancelable-false" variant="modal" cancelable="false">
    <h2 style="margin: 0 0 8px 0; font: var(--mdc-typescale-title-medium);">Not cancelable (false)</h2>
    <p>Esc and scrim taps are ignored. Use <code>close()</code> from the parent.</p>
</mdc-bottom-sheet>

<mdc-button onclick="this.getRootNode().querySelector('#bs-cancelable-true').show()"><span>Cancelable</span></mdc-button>
<mdc-button onclick="this.getRootNode().querySelector('#bs-cancelable-false').show()"><span>Not cancelable</span></mdc-button>

Detent

Code
<style>
    .demo-sheet-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 12px;
    }
    .demo-sheet-title {
        margin: 0;
        font: var(--mdc-typescale-title-medium, 500 1rem/1.5rem system-ui);
    }
    .demo-table-container {
        width: 100%;
        overflow-x: auto;
        margin: 12px 0;
    }
    .demo-table {
        width: 100%;
        border-collapse: collapse;
        text-align: left;
        font: var(--mdc-typescale-body-medium, 400 0.875rem/1.25rem system-ui);
    }
    .demo-table th {
        padding: 10px 12px;
        background: var(--mdc-color-surface-container-high, #ece6f0);
        font: var(--mdc-typescale-label-large, 500 0.875rem/1.25rem system-ui);
        border-bottom: 2px solid var(--mdc-color-outline-variant, #cac4d0);
    }
    .demo-table td {
        padding: 10px 12px;
        border-bottom: 1px solid var(--mdc-color-outline-variant, #cac4d0);
    }
    .demo-table tr:hover td {
        background: var(--mdc-color-surface-container-lowest, #fdf8fd);
    }
    .demo-badge-success {
        display: inline-block;
        padding: 2px 8px;
        border-radius: 12px;
        font-size: 11px;
        font-weight: 500;
        background: #e8f5e9;
        color: #2e7d32;
    }
    .demo-badge-warning {
        display: inline-block;
        padding: 2px 8px;
        border-radius: 12px;
        font-size: 11px;
        font-weight: 500;
        background: #fff3e0;
        color: #e65100;
    }
</style>

<mdc-bottom-sheet id="bs-detent-peek" variant="modal" detent="peek">
    <div slot="header" class="demo-sheet-header">
        <div>
            <h2 class="demo-sheet-title">Recent Files (Peek Detent - Header Slot)</h2>
            <span style="font: var(--mdc-typescale-body-small); opacity: 0.7;">Default compact height (~40vh)</span>
        </div>
        <mdc-button variant="text" onclick="this.closest('mdc-bottom-sheet').close()"><span>Close</span></mdc-button>
    </div>

    <mdc-list aria-label="Recent files list">
        <mdc-list-item type="button">
            <mdc-icon slot="start">description</mdc-icon>
            <span>Q3_Financial_Report.pdf</span>
            <span slot="supporting-text">Modified 2 hours ago · 2.4 MB</span>
            <mdc-icon slot="end">more_vert</mdc-icon>
        </mdc-list-item>
        <mdc-list-item type="button">
            <mdc-icon slot="start">image</mdc-icon>
            <span>Design_System_M3E_Hero.png</span>
            <span slot="supporting-text">Modified Yesterday · 14.8 MB</span>
            <mdc-icon slot="end">more_vert</mdc-icon>
        </mdc-list-item>
        <mdc-list-item type="button">
            <mdc-icon slot="start">code</mdc-icon>
            <span>bottom-sheet.animation.ts</span>
            <span slot="supporting-text">Modified 3 days ago · 5.6 KB</span>
            <mdc-icon slot="end">more_vert</mdc-icon>
        </mdc-list-item>
    </mdc-list>
</mdc-bottom-sheet>

<mdc-bottom-sheet id="bs-detent-full" variant="modal" detent="full">
    <div slot="header" class="demo-sheet-header">
        <div>
            <h2 class="demo-sheet-title">Order & Inventory Report (Full Detent - All Slots)</h2>
            <span style="font: var(--mdc-typescale-body-small); opacity: 0.7;">Expanded full viewport (~96vh) with tabular data</span>
        </div>
        <mdc-button variant="text" onclick="this.closest('mdc-bottom-sheet').close()"><span>Close</span></mdc-button>
    </div>

    <div class="demo-table-container">
        <table class="demo-table">
            <thead>
                <tr>
                    <th>Item ID</th>
                    <th>Product Name</th>
                    <th>Category</th>
                    <th>Status</th>
                    <th>Stock</th>
                    <th>Unit Price</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td><code>#PRD-1092</code></td>
                    <td><b>Pixel 9 Pro XL</b></td>
                    <td>Hardware</td>
                    <td><span class="demo-badge-success">In Stock</span></td>
                    <td>142</td>
                    <td>$1,099.00</td>
                </tr>
                <tr>
                    <td><code>#PRD-1093</code></td>
                    <td><b>Pixel Watch 3 (45mm)</b></td>
                    <td>Wearables</td>
                    <td><span class="demo-badge-success">In Stock</span></td>
                    <td>68</td>
                    <td>$399.00</td>
                </tr>
                <tr>
                    <td><code>#PRD-1094</code></td>
                    <td><b>Pixel Buds Pro 2</b></td>
                    <td>Audio</td>
                    <td><span class="demo-badge-warning">Low Stock</span></td>
                    <td>12</td>
                    <td>$229.00</td>
                </tr>
                <tr>
                    <td><code>#PRD-1095</code></td>
                    <td><b>45W USB-C Fast Charger</b></td>
                    <td>Accessories</td>
                    <td><span class="demo-badge-success">In Stock</span></td>
                    <td>310</td>
                    <td>$29.99</td>
                </tr>
                <tr>
                    <td><code>#PRD-1096</code></td>
                    <td><b>M3E Folio Protective Case</b></td>
                    <td>Accessories</td>
                    <td><span class="demo-badge-success">In Stock</span></td>
                    <td>85</td>
                    <td>$49.99</td>
                </tr>
            </tbody>
        </table>
    </div>

    <div style="display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px;">
        <mdc-button variant="outlined" onclick="this.closest('mdc-bottom-sheet').close()"><span>Export CSV</span></mdc-button>
        <mdc-button variant="filled" onclick="this.closest('mdc-bottom-sheet').close()"><span>Done</span></mdc-button>
    </div>
</mdc-bottom-sheet>

<mdc-button onclick="this.getRootNode().querySelector('#bs-detent-peek').show()"><span>Peek (File List)</span></mdc-button>
<mdc-button onclick="this.getRootNode().querySelector('#bs-detent-full').show()"><span>Full (Data Table)</span></mdc-button>

Draggable

Code
<style>
    .demo-sheet-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 12px;
    }
    .demo-sheet-title {
        margin: 0;
        font: var(--mdc-typescale-title-medium, 500 1rem/1.5rem system-ui);
    }
    .demo-tool-grid {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: 12px 8px;
        text-align: center;
        margin: 12px 0;
    }
    .demo-tool-btn {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 6px;
        cursor: pointer;
        background: none;
        border: none;
        padding: 4px;
        color: inherit;
        font: var(--mdc-typescale-label-medium, 500 0.75rem/1rem system-ui);
    }
    .demo-tool-icon-box {
        width: 44px;
        height: 44px;
        border-radius: 12px;
        display: flex;
        align-items: center;
        justify-content: center;
        background: var(--mdc-color-surface-container-high, #ece6f0);
        color: var(--mdc-color-primary, #6750a4);
        transition: transform 0.15s ease;
    }
    .demo-tool-btn:hover .demo-tool-icon-box {
        transform: translateY(-2px);
    }
</style>

<mdc-bottom-sheet id="bs-draggable-true" variant="modal" detent="peek" draggable>
    <div class="demo-sheet-header">
        <div>
            <h2 class="demo-sheet-title">Create & Edit Tools (Draggable)</h2>
            <span style="font: var(--mdc-typescale-body-small); opacity: 0.7;">Drag handle down to dismiss; release to snap back</span>
        </div>
        <mdc-button variant="text" onclick="this.closest('mdc-bottom-sheet').close()"><span>Close</span></mdc-button>
    </div>

    <!-- Tool Grid -->
    <div class="demo-tool-grid">
        <button class="demo-tool-btn" type="button">
            <div class="demo-tool-icon-box"><mdc-icon>add_photo_alternate</mdc-icon></div>
            <span>Photo</span>
        </button>
        <button class="demo-tool-btn" type="button">
            <div class="demo-tool-icon-box"><mdc-icon>document_scanner</mdc-icon></div>
            <span>Scan doc</span>
        </button>
        <button class="demo-tool-btn" type="button">
            <div class="demo-tool-icon-box"><mdc-icon>mic</mdc-icon></div>
            <span>Audio</span>
        </button>
        <button class="demo-tool-btn" type="button">
            <div class="demo-tool-icon-box"><mdc-icon>draw</mdc-icon></div>
            <span>Draw</span>
        </button>
    </div>

    <mdc-divider style="margin: 16px 0;"></mdc-divider>

    <!-- Detailed List Section -->
    <div style="font: var(--mdc-typescale-label-large); opacity: 0.8; margin-bottom: 4px;">More Options</div>
    <mdc-list aria-label="Tool options">
        <mdc-list-item type="button">
            <mdc-icon slot="start">folder_open</mdc-icon>
            <span>Import from Google Drive</span>
            <span slot="supporting-text">Synced automatically with workspace</span>
            <mdc-icon slot="end">chevron_right</mdc-icon>
        </mdc-list-item>
        <mdc-list-item type="button">
            <mdc-icon slot="start">settings</mdc-icon>
            <span>Canvas & Grid Settings</span>
            <span slot="supporting-text">Customize background, snap-to-grid</span>
            <mdc-icon slot="end">chevron_right</mdc-icon>
        </mdc-list-item>
    </mdc-list>
</mdc-bottom-sheet>

<mdc-bottom-sheet id="bs-draggable-false" variant="modal" detent="peek" draggable="false">
    <div class="demo-sheet-header">
        <div>
            <h2 class="demo-sheet-title">Privacy Permissions (Non-Draggable)</h2>
            <span style="font: var(--mdc-typescale-body-small); opacity: 0.7;">Swipe gestures disabled — must confirm or close explicitly</span>
        </div>
        <mdc-button variant="text" onclick="this.closest('mdc-bottom-sheet').close()"><span>Cancel</span></mdc-button>
    </div>

    <mdc-list aria-label="Privacy checkboxes">
        <mdc-list-item type="text">
            <mdc-checkbox slot="control" checked></mdc-checkbox>
            <span>Location Access</span>
            <span slot="supporting-text">Allow app to use precise location</span>
        </mdc-list-item>
        <mdc-list-item type="text">
            <mdc-checkbox slot="control" checked></mdc-checkbox>
            <span>Camera & Microphone</span>
            <span slot="supporting-text">Required for video call capture</span>
        </mdc-list-item>
        <mdc-list-item type="text">
            <mdc-checkbox slot="control"></mdc-checkbox>
            <span>Diagnostic Telemetry</span>
            <span slot="supporting-text">Help improve performance and stability</span>
        </mdc-list-item>
    </mdc-list>

    <div style="display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px;">
        <mdc-button variant="filled" onclick="this.closest('mdc-bottom-sheet').close()"><span>Save Preferences</span></mdc-button>
    </div>
</mdc-bottom-sheet>

<mdc-button onclick="this.getRootNode().querySelector('#bs-draggable-true').show()"><span>Draggable (Grid + Divider + List)</span></mdc-button>
<mdc-button onclick="this.getRootNode().querySelector('#bs-draggable-false').show()"><span>Static (Permission Checkboxes)</span></mdc-button>

Hide Drag Handle

Code
<mdc-bottom-sheet id="bs-handle-shown" variant="modal">
    <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
        <h2 style="margin: 0; font: var(--mdc-typescale-title-medium);">Handle Visible (Default)</h2>
        <mdc-button variant="text" onclick="this.closest('mdc-bottom-sheet').close()"><span>Close</span></mdc-button>
    </div>
    <mdc-list aria-label="Audio output devices">
        <mdc-list-item type="button">
            <mdc-icon slot="start">speaker</mdc-icon>
            <span>Living Room Soundbar</span>
            <span slot="supporting-text">Connected · 85% Volume</span>
        </mdc-list-item>
        <mdc-list-item type="button">
            <mdc-icon slot="start">headphones</mdc-icon>
            <span>Pixel Buds Pro 2</span>
            <span slot="supporting-text">Bluetooth · Active Noise Cancellation</span>
        </mdc-list-item>
    </mdc-list>
</mdc-bottom-sheet>

<mdc-bottom-sheet id="bs-handle-hidden" variant="modal" hide-drag-handle>
    <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
        <div>
            <h2 style="margin: 0; font: var(--mdc-typescale-title-medium);">Handle Hidden (Seamless)</h2>
            <span style="font: var(--mdc-typescale-body-small); opacity: 0.7;">Top region is still draggable</span>
        </div>
        <mdc-button variant="text" onclick="this.closest('mdc-bottom-sheet').close()"><span>Done</span></mdc-button>
    </div>
    <mdc-list aria-label="Network connections">
        <mdc-list-item type="button">
            <mdc-icon slot="start">wifi</mdc-icon>
            <span>Office-5G-Ultra</span>
            <span slot="supporting-text">Connected · 1200 Mbps</span>
            <mdc-icon slot="end">check</mdc-icon>
        </mdc-list-item>
        <mdc-list-item type="button">
            <mdc-icon slot="start">signal_cellular_alt</mdc-icon>
            <span>5G Mobile Data</span>
            <span slot="supporting-text">Carrier fallback enabled</span>
        </mdc-list-item>
    </mdc-list>
</mdc-bottom-sheet>

<mdc-button onclick="this.getRootNode().querySelector('#bs-handle-shown').show()"><span>Handle visible</span></mdc-button>
<mdc-button onclick="this.getRootNode().querySelector('#bs-handle-hidden').show()"><span>Handle hidden</span></mdc-button>

Max Height

Code
<style>
    .demo-sheet-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 12px;
    }
    .demo-sheet-title {
        margin: 0;
        font: var(--mdc-typescale-title-medium, 500 1rem/1.5rem system-ui);
    }
    .demo-table-container {
        width: 100%;
        overflow-x: auto;
        margin: 12px 0;
    }
    .demo-table {
        width: 100%;
        border-collapse: collapse;
        text-align: left;
        font: var(--mdc-typescale-body-medium, 400 0.875rem/1.25rem system-ui);
    }
    .demo-table th {
        padding: 8px 12px;
        background: var(--mdc-color-surface-container-high, #ece6f0);
        font: var(--mdc-typescale-label-large, 500 0.875rem/1.25rem system-ui);
        border-bottom: 2px solid var(--mdc-color-outline-variant, #cac4d0);
    }
    .demo-table td {
        padding: 8px 12px;
        border-bottom: 1px solid var(--mdc-color-outline-variant, #cac4d0);
    }
</style>

<mdc-bottom-sheet id="bs-maxheight-0" variant="modal" max-height="0">
    <div class="demo-sheet-header">
        <div>
            <h2 class="demo-sheet-title">Task List (No max-height cap)</h2>
            <span style="font: var(--mdc-typescale-body-small); opacity: 0.7;">Container height natural with content</span>
        </div>
        <mdc-button variant="text" onclick="this.closest('mdc-bottom-sheet').close()"><span>Close</span></mdc-button>
    </div>
    <mdc-list aria-label="Tasks list">
        <mdc-list-item type="text">
            <mdc-checkbox slot="control" checked></mdc-checkbox>
            <span>Review M3 Expressive Tokens Specification</span>
            <span slot="supporting-text">Completed by Engineering team</span>
        </mdc-list-item>
        <mdc-list-item type="text">
            <mdc-checkbox slot="control"></mdc-checkbox>
            <span>Implement Drag-to-Dismiss Gestures</span>
            <span slot="supporting-text">In Progress · ETA Today</span>
        </mdc-list-item>
        <mdc-list-item type="text">
            <mdc-checkbox slot="control"></mdc-checkbox>
            <span>Add Comprehensive Interactive Demos</span>
            <span slot="supporting-text">Pending Review</span>
        </mdc-list-item>
    </mdc-list>
</mdc-bottom-sheet>

<mdc-bottom-sheet id="bs-maxheight-400" variant="modal" max-height="400">
    <div class="demo-sheet-header">
        <div>
            <h2 class="demo-sheet-title">Transaction Ledger (max-height: 400px)</h2>
            <span style="font: var(--mdc-typescale-body-small); opacity: 0.7;">Capped at 400px; internal table scrolls vertically</span>
        </div>
        <mdc-button variant="text" onclick="this.closest('mdc-bottom-sheet').close()"><span>Close</span></mdc-button>
    </div>
    <div class="demo-table-container">
        <table class="demo-table">
            <thead>
                <tr>
                    <th>Tx ID</th>
                    <th>Description</th>
                    <th>Date</th>
                    <th>Amount</th>
                </tr>
            </thead>
            <tbody>
                <tr><td><code>#TX-901</code></td><td>AWS Cloud Infrastructure</td><td>Aug 20</td><td>-$142.50</td></tr>
                <tr><td><code>#TX-902</code></td><td>Figma Organization License</td><td>Aug 19</td><td>-$45.00</td></tr>
                <tr><td><code>#TX-903</code></td><td>Google Workspace Subscription</td><td>Aug 18</td><td>-$72.00</td></tr>
                <tr><td><code>#TX-904</code></td><td>Client Payment - Acme Corp</td><td>Aug 17</td><td>+$3,400.00</td></tr>
                <tr><td><code>#TX-905</code></td><td>GitHub Enterprise Seats</td><td>Aug 16</td><td>-$84.00</td></tr>
                <tr><td><code>#TX-906</code></td><td>Domain Registration Renewal</td><td>Aug 15</td><td>-$18.00</td></tr>
                <tr><td><code>#TX-907</code></td><td>Stripe Processing Payout</td><td>Aug 14</td><td>+$1,280.00</td></tr>
                <tr><td><code>#TX-908</code></td><td>Vercel Pro Team Plan</td><td>Aug 13</td><td>-$20.00</td></tr>
            </tbody>
        </table>
    </div>
</mdc-bottom-sheet>

<mdc-button onclick="this.getRootNode().querySelector('#bs-maxheight-0').show()"><span>Natural Height (Task List)</span></mdc-button>
<mdc-button onclick="this.getRootNode().querySelector('#bs-maxheight-400').show()"><span>400px Cap (Scrollable Table)</span></mdc-button>

No Focus Trap

Code
<mdc-bottom-sheet id="bs-focus-trap-on" variant="modal">
    <h2 style="margin: 0 0 8px 0; font: var(--mdc-typescale-title-medium);">Focus trap enabled (default)</h2>
    <p>Tab cycles within the sheet. Try tabbing from the buttons.</p>
    <mdc-button variant="text"><span>First</span></mdc-button>
    <mdc-button variant="text"><span>Last</span></mdc-button>
</mdc-bottom-sheet>

<mdc-bottom-sheet id="bs-focus-trap-off" variant="modal" no-focus-trap>
    <h2 style="margin: 0 0 8px 0; font: var(--mdc-typescale-title-medium);">Focus trap disabled</h2>
    <p>Tab leaves the sheet and moves to the page.</p>
    <mdc-button variant="text"><span>First</span></mdc-button>
    <mdc-button variant="text"><span>Last</span></mdc-button>
</mdc-bottom-sheet>

<mdc-button onclick="this.getRootNode().querySelector('#bs-focus-trap-on').show()"><span>Trap enabled</span></mdc-button>
<mdc-button onclick="this.getRootNode().querySelector('#bs-focus-trap-off').show()"><span>Trap disabled</span></mdc-button>

Open

Code
<mdc-bottom-sheet id="bs-open-imperative" variant="modal">
    <h2 style="margin: 0 0 8px 0; font: var(--mdc-typescale-title-medium);">Opened via show()</h2>
    <p>Imperative: <code>sheet.show()</code> sets <code>open</code> and promotes the dialog to the top layer.</p>
</mdc-bottom-sheet>

<mdc-bottom-sheet id="bs-open-declarative" variant="modal" open>
    <h2 style="margin: 0 0 8px 0; font: var(--mdc-typescale-title-medium);">Opened via the open property</h2>
    <p>Declarative: setting <code>open = true</code> (or the <code>open</code> attribute) drives the same lifecycle.</p>
</mdc-bottom-sheet>

<mdc-button onclick="this.getRootNode().querySelector('#bs-open-imperative').show()"><span>show()</span></mdc-button>

Quick

Code
<mdc-bottom-sheet id="bs-quick-true" variant="modal" quick>
    <h2 style="margin: 0 0 8px 0; font: var(--mdc-typescale-title-medium);">Quick (true)</h2>
    <p>Open / close jump directly to the target state — no animation.</p>
</mdc-bottom-sheet>

<mdc-bottom-sheet id="bs-quick-false" variant="modal">
    <h2 style="margin: 0 0 8px 0; font: var(--mdc-typescale-title-medium);">Quick (false, default)</h2>
    <p>Open / close animate via WAAPI.</p>
</mdc-bottom-sheet>

<mdc-button onclick="this.getRootNode().querySelector('#bs-quick-true').show()"><span>Quick</span></mdc-button>
<mdc-button onclick="this.getRootNode().querySelector('#bs-quick-false').show()"><span>Animated</span></mdc-button>

Variant

Code
<style>
    .demo-sheet-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 16px;
    }
    .demo-sheet-title {
        margin: 0;
        font: var(--mdc-typescale-title-medium, 500 1rem/1.5rem system-ui);
    }
    .demo-grid {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: 16px 8px;
        text-align: center;
        margin: 12px 0;
    }
    .demo-grid-item {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 6px;
        cursor: pointer;
        background: none;
        border: none;
        padding: 4px;
        color: inherit;
        font: var(--mdc-typescale-label-medium, 500 0.75rem/1rem system-ui);
    }
    .demo-grid-icon-circle {
        width: 48px;
        height: 48px;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        background: var(--mdc-color-surface-container-high, #ece6f0);
        color: var(--mdc-color-primary, #6750a4);
        transition: transform 0.15s ease;
    }
    .demo-grid-item:hover .demo-grid-icon-circle {
        transform: scale(1.08);
    }
</style>

<!-- Standard variant: 3 states (Closed, Peek [Header only], Full [Header + Content]) -->
<mdc-bottom-sheet id="bs-variant-standard" variant="standard" detent="peek">
    <div slot="header" class="demo-sheet-header">
        <div>
            <h2 class="demo-sheet-title">3 Photos Selected (Google Photos style)</h2>
            <span style="font: var(--mdc-typescale-body-small); opacity: 0.7;">Standard Sheet · No scrim · Background 100% interactive</span>
        </div>
        <div style="display: flex; gap: 8px;">
            <mdc-button
                variant="outlined"
                onclick="const s = this.closest('mdc-bottom-sheet'); s.detent = s.detent === 'peek' ? 'full' : 'peek'"
            >
                <span>Toggle Peek / Full</span>
            </mdc-button>
            <mdc-button variant="text" onclick="this.closest('mdc-bottom-sheet').close()"><span>Close</span></mdc-button>
        </div>
    </div>

    <!-- Lower slot (content / details): displayed only in 'full' state -->
    <div style="margin-top: 8px;">
        <h3 style="margin: 0 0 8px 0; font: var(--mdc-typescale-title-small);">Detailed Information & Operations</h3>
        <p style="margin: 0 0 12px 0; font: var(--mdc-typescale-body-small); opacity: 0.8;">
            Captured on August 20, 2026 · Sony A7R V · 24-70mm F2.8 GM II · Location: Tokyo, Japan
        </p>
        <mdc-list aria-label="Photo operations">
            <mdc-list-item type="button">
                <mdc-icon slot="start">share</mdc-icon>
                <span>Share Album to Contacts</span>
                <span slot="supporting-text">Send high-res link via cloud</span>
                <mdc-icon slot="end">chevron_right</mdc-icon>
            </mdc-list-item>
            <mdc-list-item type="button">
                <mdc-icon slot="start">auto_fix_high</mdc-icon>
                <span>Enhance & Magic Eraser</span>
                <span slot="supporting-text">AI background cleanup & color boost</span>
                <mdc-icon slot="end">chevron_right</mdc-icon>
            </mdc-list-item>
            <mdc-list-item type="button">
                <mdc-icon slot="start">drive_file_move</mdc-icon>
                <span>Move to Locked Folder</span>
                <span slot="supporting-text">Protected by biometrics</span>
                <mdc-icon slot="end">chevron_right</mdc-icon>
            </mdc-list-item>
            <mdc-list-item type="button">
                <mdc-icon slot="start">delete_outline</mdc-icon>
                <span>Move to Trash</span>
                <span slot="supporting-text">Items in trash deleted after 30 days</span>
                <mdc-icon slot="end">chevron_right</mdc-icon>
            </mdc-list-item>
        </mdc-list>
    </div>
</mdc-bottom-sheet>

<!-- Modal variant -->
<mdc-bottom-sheet id="bs-variant-modal" variant="modal">
    <div slot="header" class="demo-sheet-header">
        <h2 class="demo-sheet-title">Share & Actions (Modal with Scrim)</h2>
        <mdc-button variant="text" onclick="this.closest('mdc-bottom-sheet').close()"><span>Done</span></mdc-button>
    </div>

    <!-- First Grid Section: Share channels -->
    <div style="font: var(--mdc-typescale-label-large); opacity: 0.8; margin-bottom: 4px;">Share via</div>
    <div class="demo-grid">
        <button class="demo-grid-item" type="button">
            <div class="demo-grid-icon-circle"><mdc-icon>chat</mdc-icon></div>
            <span>Messages</span>
        </button>
        <button class="demo-grid-item" type="button">
            <div class="demo-grid-icon-circle"><mdc-icon>mail</mdc-icon></div>
            <span>Email</span>
        </button>
        <button class="demo-grid-item" type="button">
            <div class="demo-grid-icon-circle"><mdc-icon>cloud_upload</mdc-icon></div>
            <span>Drive</span>
        </button>
        <button class="demo-grid-item" type="button">
            <div class="demo-grid-icon-circle"><mdc-icon>bluetooth</mdc-icon></div>
            <span>Nearby</span>
        </button>
    </div>

    <mdc-divider style="margin: 16px 0;"></mdc-divider>

    <!-- Second Grid Section: File Actions -->
    <div style="font: var(--mdc-typescale-label-large); opacity: 0.8; margin-bottom: 4px;">Actions</div>
    <div class="demo-grid">
        <button class="demo-grid-item" type="button">
            <div class="demo-grid-icon-circle"><mdc-icon>content_copy</mdc-icon></div>
            <span>Copy link</span>
        </button>
        <button class="demo-grid-item" type="button">
            <div class="demo-grid-icon-circle"><mdc-icon>bookmark_border</mdc-icon></div>
            <span>Bookmark</span>
        </button>
        <button class="demo-grid-item" type="button">
            <div class="demo-grid-icon-circle"><mdc-icon>print</mdc-icon></div>
            <span>Print</span>
        </button>
        <button class="demo-grid-item" type="button">
            <div class="demo-grid-icon-circle"><mdc-icon>qr_code</mdc-icon></div>
            <span>QR Code</span>
        </button>
    </div>
</mdc-bottom-sheet>

<mdc-button onclick="const s = this.getRootNode().querySelector('#bs-variant-standard'); s.detent = 'peek'; s.show()"><span>Standard (Peek State - Header Only)</span></mdc-button>
<mdc-button onclick="const s = this.getRootNode().querySelector('#bs-variant-standard'); s.detent = 'full'; s.show()"><span>Standard (Full State - All Slots)</span></mdc-button>
<mdc-button onclick="const s = this.getRootNode().querySelector('#bs-variant-modal'); s.detent = 'peek'; s.show()"><span>Modal (Peek State)</span></mdc-button>
<mdc-button onclick="const s = this.getRootNode().querySelector('#bs-variant-modal'); s.detent = 'full'; s.show()"><span>Modal (Full State)</span></mdc-button>