description Layout Demonstration - All Types

Single form showcasing Vertical, Horizontal, Tabbed, and List layouts Async

Personal Info

Vertical layout demonstration

Your given name
Your family name
Your email address
event
Your birth date (optional)
Debug panel (development only)
<!-- Material Design 3 Self-Contained Form -->
<style>
/* Material Design 3 Self-Contained Styles - Using !important to override any conflicting styles */
.md-form-container {
    font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
    max-width: 100% !important;
    margin: 0 !important;
    padding: 20px !important;
    line-height: 1.5 !important;
    color: #1c1b1f !important;
    background: #fef7ff !important;
    border: none !important;
    box-sizing: border-box !important;
    position: relative !important;
}

.md-form {
    width: 100% !important;
    background: #ffffff !important;
    border-radius: 28px !important;
    padding: 32px !important;
    box-shadow: 0 1px 2px rgba(0,0,0,0.3), 0 2px 6px 2px rgba(0,0,0,0.15) !important;
    border: none !important;
    margin: 0 !important;
    box-sizing: border-box !important;
    font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
}

/* Reset any Bootstrap interference */
.md-form * {
    box-sizing: border-box !important;
}

/* Material Design Form Fields */
.md-field {
    margin-bottom: 32px !important;
    position: relative !important;
    width: 100% !important;
    font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
}

/* Model list container styling to blend with Material Design */
.md-model-list-container {
    background: transparent !important;
    border: none !important;
    padding: 0 !important;
    margin: 0 !important;
    font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
}

/* Override Bootstrap styles for model list items within Material Design */
.md-model-list-container .card {
    border: 1px solid #79747e !important;
    border-radius: 12px !important;
    box-shadow: none !important;
    margin-bottom: 16px !important;
    background: #ffffff !important;
}

.md-model-list-container .card-header {
    background: #f7f2fa !important;
    border-bottom: 1px solid #e7e0ec !important;
    border-radius: 12px 12px 0 0 !important;
    color: #1c1b1f !important;
    font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
    font-weight: 500 !important;
}

.md-model-list-container .btn {
    border-radius: 20px !important;
    font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
    font-weight: 500 !important;
    text-transform: none !important;
}

.md-model-list-container .btn-primary {
    background: #6750a4 !important;
    border-color: #6750a4 !important;
}

.md-model-list-container .btn-danger {
    background: #ba1a1a !important;
    border-color: #ba1a1a !important;
}

.md-model-list-wrapper {
    background: transparent !important;
    margin-bottom: 32px !important;
}

.md-model-list-container {
    border: 1px solid #e7e0ec !important;
    border-radius: 24px !important;
    padding: 16px 20px !important;
    background: #fff !important;
    box-shadow: 0 1px 3px rgba(0,0,0,0.08) !important;
}

.md-model-list-items {
    display: flex !important;
    flex-direction: column !important;
    gap: 16px !important;
}

.md-model-card {
    border: 1px solid #e7e0ec !important;
    border-radius: 20px !important;
    background: #ffffff !important;
    padding: 16px 20px !important;
    box-shadow: 0 1px 3px rgba(0,0,0,0.08) !important;
}

.md-model-card__header {
    display: flex !important;
    justify-content: space-between !important;
    align-items: center !important;
    margin-bottom: 12px !important;
}

.md-model-card__body {
    padding: 0 !important;
}

.md-model-list-actions {
    margin-top: 12px !important;
    display: flex !important;
    justify-content: flex-end !important;
}

.md-button-tonal {
    background: #e8def8 !important;
    color: #1c1b1f !important;
}

.md-button-tonal:hover {
    background: #cdc2db !important;
}

.md-button__icon {
    margin-right: 8px !important;
    width: 20px !important;
    height: 20px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    flex: 0 0 20px !important;
    fill: currentColor !important;
}

.md-button__label {
    font-weight: 500 !important;
}

/* Layout card styling */
.md-layout-card {
    background: #ffffff !important;
    border-radius: 24px !important;
    padding: 24px 28px !important;
    margin-bottom: 32px !important;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2), 0 4px 8px rgba(0,0,0,0.1) !important;
    border: 1px solid #e7e0ec !important;
}

.md-layout-card__header {
    margin-bottom: 12px !important;
}

.md-layout-card__title {
    font-size: 18px !important;
    font-weight: 600 !important;
    color: #1c1b1f !important;
}

.md-layout-card__help {
    color: #49454f !important;
    font-size: 14px !important;
    margin-bottom: 12px !important;
}

.md-layout-card__content {
    display: flex !important;
    flex-direction: column !important;
    gap: 16px !important;
}

.md-field-label {
    display: block !important;
    color: #49454f !important;
    font-size: 14px !important;
    font-weight: 500 !important;
    margin-bottom: 8px !important;
    position: relative !important;
    font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
    line-height: 1.4 !important;
}

.md-field-label.required::after {
    content: ' *' !important;
    color: #ba1a1a !important;
}

/* Material Design Outlined Text Fields */
.md-text-field {
    position: relative;
    width: 100%;
}

/* Field container */
.md-field {
    margin: 16px 0;
}

/* Field with icon layout */
.md-field-with-icon {
    display: flex !important;
    align-items: flex-start !important;
    gap: 12px !important;
    font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
}

/* Input wrapper for proper label positioning */
.md-input-wrapper {
    position: relative !important;
    flex: 1 !important;
    width: 100% !important;
}

.md-input {
    width: 100% !important;
    padding: 16px !important;
    border: 1px solid #79747e !important;
    border-radius: 4px !important;
    background: transparent !important;
    color: #1c1b1f !important;
    font-size: 16px !important;
    font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
    outline: none !important;
    transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1) !important;
    box-sizing: border-box !important;
    line-height: 1.5 !important;
    margin: 0 !important;
}

.md-input:focus {
    border-color: #6750a4 !important;
    border-width: 2px !important;
    padding: 15px !important; /* Adjust for thicker border */
    box-shadow: none !important;
}

/* Icon styling - positioned outside to the left of input */
.md-icon {
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    width: 24px !important;
    height: 24px !important;
    margin-top: 16px !important; /* Align with input padding */
    color: #49454f !important;
    flex-shrink: 0 !important;
    transition: color 0.15s cubic-bezier(0.4, 0, 0.2, 1) !important;
    fill: currentColor !important;
}

.md-field-with-icon:focus-within .md-icon {
    color: #6750a4 !important;
}

.md-input:focus + .md-floating-label,
.md-input:not(:placeholder-shown) + .md-floating-label,
.md-textarea:focus + .md-floating-label,
.md-textarea:not(:placeholder-shown) + .md-floating-label,
.md-select:focus + .md-floating-label {
    transform: translateY(-28px) scale(0.75) !important;
    color: #6750a4 !important;
    background: #ffffff !important;
    padding: 0 4px !important;
}

.md-floating-label {
    position: absolute !important;
    left: 16px !important;
    top: 16px !important;
    color: #49454f !important;
    font-size: 16px !important;
    transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1) !important;
    pointer-events: none !important;
    background: transparent !important;
    z-index: 1 !important;
    transform-origin: left top !important;
    font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
    font-weight: 400 !important;
    line-height: 1.4 !important;
}

.md-input:focus + .md-floating-label,
.md-input:not(:placeholder-shown) + .md-floating-label {
    transform: translateY(-28px) scale(0.75) !important;
    color: #6750a4;
    background: #ffffff;
    padding: 0 4px;
}

.md-input.error {
    border-color: #ba1a1a;
}

.md-input.error:focus {
    border-color: #ba1a1a;
}

.md-input.error + .md-floating-label {
    color: #ba1a1a;
}

/* Material Design Select */
.md-select {
    width: 100%;
    padding: 16px;
    border: 1px solid #79747e;
    border-radius: 4px;
    background: transparent;
    color: #1c1b1f;
    font-size: 16px;
    font-family: inherit;
    outline: none;
    cursor: pointer;
    transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
    box-sizing: border-box;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%2349454f' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3e%3c/svg%3e");
    background-position: right 12px center;
    background-repeat: no-repeat;
    background-size: 16px;
    padding-right: 40px;
}

.md-select:focus {
    border-color: #6750a4;
    border-width: 2px;
    padding: 15px 39px 15px 15px; /* Adjust for thicker border */
}

.md-select:focus + .md-floating-label {
    transform: translateY(-28px) scale(0.75);
    color: #6750a4;
    background: #ffffff;
    padding: 0 4px;
}

/* Material Design Textarea */
.md-textarea {
    width: 100%;
    min-height: 120px;
    padding: 16px;
    border: 1px solid #79747e;
    border-radius: 4px;
    background: transparent;
    color: #1c1b1f;
    font-size: 16px;
    font-family: inherit;
    outline: none;
    resize: vertical;
    transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
    box-sizing: border-box;
}

.md-textarea:focus {
    border-color: #6750a4;
    border-width: 2px;
    padding: 15px; /* Adjust for thicker border */
}

.md-textarea:focus + .md-floating-label,
.md-textarea:not(:placeholder-shown) + .md-floating-label {
    transform: translateY(-28px) scale(0.75);
    color: #6750a4;
    background: #ffffff;
    padding: 0 4px;
}

/* Material Design Checkboxes */
.md-checkbox-container {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    margin: 16px 0;
    cursor: pointer;
}

.md-checkbox {
    width: 18px;
    height: 18px;
    border: 2px solid #79747e;
    border-radius: 2px;
    background: transparent;
    cursor: pointer;
    position: relative;
    transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    margin-top: 2px; /* Align with text baseline */
    flex-shrink: 0;
}

.md-checkbox:checked {
    background: #6750a4;
    border-color: #6750a4;
}

.md-checkbox:checked::after {
    content: '';
    position: absolute;
    top: 1px;
    left: 4px;
    width: 6px;
    height: 10px;
    border: solid white;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

.md-checkbox-label {
    color: #1c1b1f;
    font-size: 16px;
    cursor: pointer;
    line-height: 1.5;
}

/* Material Design Buttons */
.md-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 10px 24px;
    border: none;
    border-radius: 20px;
    font-size: 14px;
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
    text-decoration: none;
    box-sizing: border-box;
    min-width: 64px;
    height: 40px;
    position: relative;
    overflow: hidden;
}

.md-button-filled {
    background: #6750a4;
    color: #ffffff;
    box-shadow: 0 1px 2px rgba(0,0,0,0.3), 0 1px 3px 1px rgba(0,0,0,0.15);
}

.md-button-filled:hover {
    background: #5a43a0;
    box-shadow: 0 1px 2px rgba(0,0,0,0.3), 0 2px 6px 2px rgba(0,0,0,0.15);
    transform: translateY(-1px);
}

.md-button-filled:active {
    transform: translateY(0);
    box-shadow: 0 1px 2px rgba(0,0,0,0.3), 0 1px 3px 1px rgba(0,0,0,0.15);
}

/* Help Text */
.md-help-text {
    font-size: 12px;
    color: #49454f;
    margin-top: 4px;
    line-height: 1.33;
    padding-left: 16px;
}

/* Error Text */
.md-error-text {
    font-size: 12px;
    color: #ba1a1a;
    margin-top: 4px;
    line-height: 1.33;
    font-weight: 400;
    padding-left: 16px;
}

/* Number and Date Inputs */
.md-input[type="number"],
.md-input[type="date"],
.md-input[type="email"],
.md-input[type="password"],
.md-input[type="tel"],
.md-input[type="url"] {
    /* Inherit all md-input styles */
}

.md-input[type="color"] {
    height: 56px;
    padding: 8px;
    cursor: pointer;
}

.md-input[type="range"] {
    padding: 16px 8px;
}

/* Placeholder styling */
.md-input::placeholder {
    color: transparent;
}

.md-input:focus::placeholder {
    color: #49454f;
}

/* State layers for interactive elements */
.md-button-filled::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: currentColor;
    opacity: 0;
    transition: opacity 0.15s cubic-bezier(0.4, 0, 0.2, 1);
    border-radius: inherit;
}

.md-button-filled:hover::before {
    opacity: 0.08;
}

.md-button-filled:focus::before {
    opacity: 0.12;
}

.md-button-filled:active::before {
    opacity: 0.16;
}

/* Responsive Design */
@media (max-width: 768px) {
    .md-form {
        padding: 24px 16px;
        border-radius: 28px;
    }

    .md-field {
        margin-bottom: 24px;
    }
}

/* Typography Scale */
.md-headline-small {
    font-size: 24px;
    font-weight: 400;
    line-height: 32px;
    color: #1c1b1f;
}

.md-body-large {
    font-size: 16px;
    font-weight: 400;
    line-height: 24px;
    color: #1c1b1f;
}

.md-body-medium {
    font-size: 14px;
    font-weight: 400;
    line-height: 20px;
    color: #49454f;
}

.md-label-large {
    font-size: 14px;
    font-weight: 500;
    line-height: 20px;
    color: #1c1b1f;
}

/* Surface colors and elevation */
.md-surface {
    background: #fef7ff;
    color: #1c1b1f;
}

.md-surface-container {
    background: #f3f0ff;
    color: #1c1b1f;
}

.md-surface-container-high {
    background: #e7e0ec;
    color: #1c1b1f;
}
</style>

<div class="md-form-container">

<form id=""
      class="pydantic-form md-form col s12"
      style=""
      method="POST"
      action="/layouts?style=material"
      novalidate>
    
    
<div class="tab-layout md-tab-layout layout-tabbed-section" style="">
    <div class="tab-navigation md-tab-navigation" role="tablist">
<button class="tab-button md-tab-button active" type="button" role="tab"
        aria-selected="true" aria-controls="tab-0" onclick="switchTab('tab-0', this)">
    Personal Info
</button>


<button class="tab-button md-tab-button" type="button" role="tab"
        aria-selected="false" aria-controls="tab-1" onclick="switchTab('tab-1', this)">
    Contact Info
</button>


<button class="tab-button md-tab-button" type="button" role="tab"
        aria-selected="false" aria-controls="tab-2" onclick="switchTab('tab-2', this)">
    Preferences
</button>


<button class="tab-button md-tab-button" type="button" role="tab"
        aria-selected="false" aria-controls="tab-3" onclick="switchTab('tab-3', this)">
    Task List
</button>
</div>
    <div class="tab-content md-tab-content">
<div id="tab-0"
     class="tab-panel active"
     role="tabpanel"
     style="display: block;"
     aria-hidden="false">
    <section class="md-layout-card">
  <header class="md-layout-card__header">
    <span class="md-layout-card__title">Personal Info</span>
  </header>
  <div class="md-layout-card__body">
    <p class="md-layout-card__help">Vertical layout demonstration</p>
    <div class="md-layout-card__content">
      
<div class="md-field">
    
<div class="md-field-with-icon">
    <svg class="material-icons md-icon" viewBox="0 0 24 24" focusable="false" aria-hidden="true"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" /></svg>
    
<div class="md-input-wrapper">
    
<input type="text"
       name="first_name"
       id="first_name"
       class="md-input"
       value="Alex"
        placeholder=" " >

    <label class="md-floating-label" for="first_name">First Name *</label>
</div>

</div>

    
<div class="md-help-text">Your given name</div>

    
</div>


<div class="md-field">
    
<div class="md-field-with-icon">
    <svg class="material-icons md-icon" viewBox="0 0 24 24" focusable="false" aria-hidden="true"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" /></svg>
    
<div class="md-input-wrapper">
    
<input type="text"
       name="last_name"
       id="last_name"
       class="md-input"
       value="Johnson"
        placeholder=" " >

    <label class="md-floating-label" for="last_name">Last Name *</label>
</div>

</div>

    
<div class="md-help-text">Your family name</div>

    
</div>


<div class="md-field">
    
<div class="md-field-with-icon">
    <svg class="material-icons md-icon" viewBox="0 0 24 24" focusable="false" aria-hidden="true"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4-8 5-8-5V6l8 5 8-5v2z" /></svg>
    
<div class="md-input-wrapper">
    
<input type="email"
       name="email"
       id="email"
       class="md-input"
       value="alex.johnson@example.com"
        placeholder=" " >

    <label class="md-floating-label" for="email">Email Address *</label>
</div>

</div>

    
<div class="md-help-text">Your email address</div>

    
</div>


<div class="md-field">
    
<div class="md-field-with-icon">
    <span class="material-icons md-icon">event</span>
    
<div class="md-input-wrapper">
    
<input type="date"
       name="birth_date"
       id="birth_date"
       class="md-input"
       value="1990-05-15"
        placeholder=" " >

    <label class="md-floating-label" for="birth_date">Date of Birth</label>
</div>

</div>

    
<div class="md-help-text">Your birth date (optional)</div>

    
</div>

    </div>
  </div>
</section>
</div>


<div id="tab-1"
     class="tab-panel"
     role="tabpanel"
     style="display: none;"
     aria-hidden="true">
    <section class="md-layout-card">
  <header class="md-layout-card__header">
    <span class="md-layout-card__title">Contact Info</span>
  </header>
  <div class="md-layout-card__body">
    <p class="md-layout-card__help">Horizontal layout demonstration</p>
    <div class="md-layout-card__content">
      
<div class="md-field">
    
<div class="md-field-with-icon">
    <span class="material-icons md-icon">phone</span>
    
<div class="md-input-wrapper">
    
<input type="tel"
       name="phone"
       id="phone"
       class="md-input"
       value="+1 (555) 987-6543"
        placeholder=" " >

    <label class="md-floating-label" for="phone">Phone Number</label>
</div>

</div>

    
<div class="md-help-text">Your contact phone number</div>

    
</div>


<div class="md-field">
    
<div class="md-field-with-icon">
    <span class="material-icons md-icon">home</span>
    
<div class="md-input-wrapper">
    
<input type="text"
       name="address"
       id="address"
       class="md-input"
       value="456 Demo Street"
        placeholder=" " >

    <label class="md-floating-label" for="address">Street Address *</label>
</div>

</div>

    
<div class="md-help-text">Your street address</div>

    
</div>


<div class="md-field">
    
<div class="md-field-with-icon">
    <span class="material-icons md-icon">building</span>
    
<div class="md-input-wrapper">
    
<input type="text"
       name="city"
       id="city"
       class="md-input"
       value="San Francisco"
        placeholder=" " >

    <label class="md-floating-label" for="city">City *</label>
</div>

</div>

    
<div class="md-help-text">City where you live</div>

    
</div>


<div class="md-field">
    
<div class="md-field-with-icon">
    <span class="material-icons md-icon">mail</span>
    
<div class="md-input-wrapper">
    
<input type="text"
       name="postal_code"
       id="postal_code"
       class="md-input"
       value="94102"
        placeholder=" " >

    <label class="md-floating-label" for="postal_code">Postal Code</label>
</div>

</div>

    
<div class="md-help-text">ZIP or postal code</div>

    
</div>

    </div>
  </div>
</section>
</div>


<div id="tab-2"
     class="tab-panel"
     role="tabpanel"
     style="display: none;"
     aria-hidden="true">
    <section class="md-layout-card">
  <header class="md-layout-card__header">
    <span class="md-layout-card__title">Preferences</span>
  </header>
  <div class="md-layout-card__body">
    <p class="md-layout-card__help">Tabbed layout demonstration</p>
    <div class="md-layout-card__content">
      
<div class="md-field">
    <div class="md-checkbox-container">
        <input type="checkbox"
               name="notification_email"
               id="notification_email"
               class="md-checkbox"
               value="true"
               checked="checked">
        <label for="notification_email" class="md-checkbox-label">Email Notifications</label>
    </div>
    
<div class="md-help-text">Receive notifications via email</div>

    
</div>


<div class="md-field">
    <div class="md-checkbox-container">
        <input type="checkbox"
               name="notification_sms"
               id="notification_sms"
               class="md-checkbox"
               value="true"
               >
        <label for="notification_sms" class="md-checkbox-label">SMS Notifications</label>
    </div>
    
<div class="md-help-text">Receive notifications via SMS</div>

    
</div>


<div class="md-field">
    
<div class="md-field-with-icon">
    <span class="material-icons md-icon">palette</span>
    
<div class="md-input-wrapper">
    
<select name="theme"
        id="theme"
        class="md-select">
    
<option value=""></option>

<option value="light">β˜€οΈ Light Theme</option>

<option value="dark" selected="selected">πŸŒ™ Dark Theme</option>

<option value="auto">πŸ”„ Auto (System)</option>

</select>

    <label class="md-floating-label" for="theme">UI Theme</label>
</div>

</div>

    
<div class="md-help-text">Choose your preferred theme</div>

    
</div>


<div class="md-field">
    
<div class="md-field-with-icon">
    <span class="material-icons md-icon">public</span>
    
<div class="md-input-wrapper">
    
<select name="language"
        id="language"
        class="md-select">
    
<option value=""></option>

<option value="en" selected="selected">πŸ‡ΊπŸ‡Έ English</option>

<option value="es">πŸ‡ͺπŸ‡Έ Spanish</option>

<option value="fr">πŸ‡«πŸ‡· French</option>

<option value="de">πŸ‡©πŸ‡ͺ German</option>

</select>

    <label class="md-floating-label" for="language">Language</label>
</div>

</div>

    
<div class="md-help-text">Select your preferred language</div>

    
</div>

    </div>
  </div>
</section>
</div>


<div id="tab-3"
     class="tab-panel"
     role="tabpanel"
     style="display: none;"
     aria-hidden="true">
    <section class="md-layout-card">
  <header class="md-layout-card__header">
    <span class="md-layout-card__title">Task List</span>
  </header>
  <div class="md-layout-card__body">
    <p class="md-layout-card__help">List layout demonstration</p>
    <div class="md-layout-card__content">
      
<div class="md-field">
    
<div class="md-field-with-icon">
    <span class="material-icons md-icon">folder</span>
    
<div class="md-input-wrapper">
    
<input type="text"
       name="project_name"
       id="project_name"
       class="md-input"
       value="Website Redesign Project"
        placeholder=" " >

    <label class="md-floating-label" for="project_name">Project Name *</label>
</div>

</div>

    
<div class="md-help-text">Name of the project or task collection</div>

    
</div>


<div class="md-field">
    <div class="md-model-list-container">
        <section class="md-model-list-wrapper">
  <label class="md-field-label required">Task List</label>
  <div class="model-list-container md-model-list-container" data-field-name="tasks"        data-min-items="1" data-max-items="10">
    <div class="model-list-items md-model-list-items"          id="tasks-items">
      
        <div class="model-list-item card border mb-3"
             data-index="0"
             data-title-template="Item #{index}"
             data-field-name="tasks">
            <div class="card-header d-flex justify-content-between align-items-center">
                <h6 class="mb-0">
                    <button class="btn btn-link text-decoration-none p-0 text-start"
                            type="button"
                            data-bs-toggle="collapse"
                            data-bs-target="#tasks_item_0_content"
                            aria-expanded="true"
                            aria-controls="tasks_item_0_content">
                        <i class="bi bi-chevron-down me-2"></i>
                        <i class="bi bi-card-list me-2"></i>
                        Item #1
                    </button>
                </h6>
                <button type="button"
                        class="btn btn-outline-danger btn-sm remove-item-btn"
                        data-index="0"
                        data-field-name="tasks"
                        title="Remove this item">
                    <i class="bi bi-trash"></i>
                </button>
            </div>
            <div class="collapse  show" id="tasks_item_0_content">
                <div class="card-body"><div class="row">
                <div class="col-md-6">
                    <div class="input-field col s12"><label for="tasks[0].task_name"><i class="material-icons">check_box</i> Task Description</label>
<input name="tasks[0].task_name" id="tasks[0].task_name" class="validate" value="Complete project setup and requirements gathering" minlength="1" maxlength="11" placeholder="Enter task description..." pattern="\d{3}-\d{2}-\d{4}" inputmode="numeric" autocomplete="off" type="text" />
<div class="help-text">What needs to be done?</div></div>
                </div>
                <div class="col-md-6">
                    <div class="input-field col s12"><div class="md-field">
<div class="md-field-with-icon">
<span class="md-icon material-icons">warning</span>
<div class="md-input-wrapper">
<select name="tasks[0].priority" id="tasks[0].priority" class="browser-default"><option value="low">🟒 Low</option>
<option value="medium">🟑 Medium</option>
<option value="high" selected>🟠 High</option>
<option value="urgent">πŸ”΄ Urgent</option></select>
<label class="md-floating-label" for="tasks[0].priority">Priority</label>
</div>
</div>
<div class="md-help-text">How important is this task?</div>
</div></div>
                </div>
                <div class="col-md-6">
                    <div class="input-field col s12"><label for="tasks[0].due_date"><i class="material-icons">event</i> Due Date</label>
<div class="birthdate-input-group"><input name="tasks[0].due_date" id="tasks[0].due_date" class="validate" value="2024-12-01" max="2026-01-07" min="1876-01-01" type="date" />
            <div class="age-display" id="tasks[0].due_date_age" style="margin-top: 5px; font-size: 0.9em; color: #666;"></div>
            <script>
            document.addEventListener('DOMContentLoaded', function() {
                const birthdateField = document.getElementById('tasks[0].due_date');
                const ageDisplay = document.getElementById('tasks[0].due_date_age');

                function calculateAge() {
                    if (birthdateField.value && ageDisplay) {
                        const birthDate = new Date(birthdateField.value);
                        const today = new Date();
                        let age = today.getFullYear() - birthDate.getFullYear();
                        const monthDiff = today.getMonth() - birthDate.getMonth();

                        if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
                            age--;
                        }

                        ageDisplay.textContent = age >= 0 ? `Age: ${age} years` : '';
                    }
                }

                if (birthdateField) {
                    birthdateField.addEventListener('change', calculateAge);
                    calculateAge(); // Calculate on load if value is set
                }
            });
            </script>
            </div>
<div class="help-text">When should this be completed? (optional)</div></div>
                </div>
                <div class="col-md-6">
                    <div class="input-field col s12"><label for="tasks[0].completed"><i class="material-icons">check</i> Completed</label>
<input name="tasks[0].completed" id="tasks[0].completed" class="filled-in" value="1" type="checkbox" />
<div class="help-text">Is this task done?</div></div>
                </div></div>
                </div>
            </div>
        </div>
        <div class="model-list-item card border mb-3"
             data-index="1"
             data-title-template="Item #{index}"
             data-field-name="tasks">
            <div class="card-header d-flex justify-content-between align-items-center">
                <h6 class="mb-0">
                    <button class="btn btn-link text-decoration-none p-0 text-start"
                            type="button"
                            data-bs-toggle="collapse"
                            data-bs-target="#tasks_item_1_content"
                            aria-expanded="true"
                            aria-controls="tasks_item_1_content">
                        <i class="bi bi-chevron-down me-2"></i>
                        <i class="bi bi-card-list me-2"></i>
                        Item #2
                    </button>
                </h6>
                <button type="button"
                        class="btn btn-outline-danger btn-sm remove-item-btn"
                        data-index="1"
                        data-field-name="tasks"
                        title="Remove this item">
                    <i class="bi bi-trash"></i>
                </button>
            </div>
            <div class="collapse  show" id="tasks_item_1_content">
                <div class="card-body"><div class="row">
                <div class="col-md-6">
                    <div class="input-field col s12"><label for="tasks[1].task_name"><i class="material-icons">check_box</i> Task Description</label>
<input name="tasks[1].task_name" id="tasks[1].task_name" class="validate" value="Design mockups and wireframes" minlength="1" maxlength="11" placeholder="Enter task description..." pattern="\d{3}-\d{2}-\d{4}" inputmode="numeric" autocomplete="off" type="text" />
<div class="help-text">What needs to be done?</div></div>
                </div>
                <div class="col-md-6">
                    <div class="input-field col s12"><div class="md-field">
<div class="md-field-with-icon">
<span class="md-icon material-icons">warning</span>
<div class="md-input-wrapper">
<select name="tasks[1].priority" id="tasks[1].priority" class="browser-default"><option value="low">🟒 Low</option>
<option value="medium" selected>🟑 Medium</option>
<option value="high">🟠 High</option>
<option value="urgent">πŸ”΄ Urgent</option></select>
<label class="md-floating-label" for="tasks[1].priority">Priority</label>
</div>
</div>
<div class="md-help-text">How important is this task?</div>
</div></div>
                </div>
                <div class="col-md-6">
                    <div class="input-field col s12"><label for="tasks[1].due_date"><i class="material-icons">event</i> Due Date</label>
<div class="birthdate-input-group"><input name="tasks[1].due_date" id="tasks[1].due_date" class="validate" value="2024-12-15" max="2026-01-07" min="1876-01-01" type="date" />
            <div class="age-display" id="tasks[1].due_date_age" style="margin-top: 5px; font-size: 0.9em; color: #666;"></div>
            <script>
            document.addEventListener('DOMContentLoaded', function() {
                const birthdateField = document.getElementById('tasks[1].due_date');
                const ageDisplay = document.getElementById('tasks[1].due_date_age');

                function calculateAge() {
                    if (birthdateField.value && ageDisplay) {
                        const birthDate = new Date(birthdateField.value);
                        const today = new Date();
                        let age = today.getFullYear() - birthDate.getFullYear();
                        const monthDiff = today.getMonth() - birthDate.getMonth();

                        if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
                            age--;
                        }

                        ageDisplay.textContent = age >= 0 ? `Age: ${age} years` : '';
                    }
                }

                if (birthdateField) {
                    birthdateField.addEventListener('change', calculateAge);
                    calculateAge(); // Calculate on load if value is set
                }
            });
            </script>
            </div>
<div class="help-text">When should this be completed? (optional)</div></div>
                </div>
                <div class="col-md-6">
                    <div class="input-field col s12"><label for="tasks[1].completed"><i class="material-icons">check</i> Completed</label>
<input name="tasks[1].completed" id="tasks[1].completed" class="filled-in" value="1" type="checkbox" />
<div class="help-text">Is this task done?</div></div>
                </div></div>
                </div>
            </div>
        </div>
    </div>
    <div class="md-model-list-actions">
      <button type="button" class="md-button md-button-tonal add-item-btn"               data-target="tasks">
        <svg class="material-icons md-button__icon" viewBox="0 0 24 24" focusable="false" aria-hidden="true"><path d="M19 13H13v6h-2v-6H5v-2h6V5h2v6h6v2z" /></svg>
        <span class="md-button__label">Add Item</span>
      </button>
    </div>
  </div>
  <p class="md-help-text">Manage your tasks (dynamic list demonstration)</p>
</section>
    </div>
</div>

    </div>
  </div>
</section>
</div>
</div>
</div>

<script>
function switchTab(tabId, buttonElement) {
    const tabLayout = buttonElement.closest('.tab-layout');
    const panels = tabLayout.querySelectorAll('.tab-panel');
    const buttons = tabLayout.querySelectorAll('.tab-button');

    panels.forEach(panel => {
        panel.style.display = 'none';
        panel.setAttribute('aria-hidden', 'true');
    });

    buttons.forEach(button => {
        button.classList.remove('active');
        button.setAttribute('aria-selected', 'false');
    });

    const selectedPanel = document.getElementById(tabId);
    if (selectedPanel) {
        selectedPanel.style.display = 'block';
        selectedPanel.setAttribute('aria-hidden', 'false');
    }

    buttonElement.classList.add('active');
    buttonElement.setAttribute('aria-selected', 'true');
}
</script>
<style>
.md-form-container .tab-layout {
    border-radius: 28px !important;
    background: #fff !important;
    border: 1px solid #e7e0ec !important;
    padding: 16px 24px !important;
    margin-bottom: 28px !important;
    box-shadow: 0 2px 6px rgba(0,0,0,0.08) !important;
}

.md-form-container .tab-layout .tab-navigation {
    display: flex !important;
    gap: 4px !important;
    border-bottom: 1px solid #e7e0ec !important;
    margin-bottom: 16px !important;
}

.md-form-container .tab-layout .tab-button {
    border: none !important;
    background: transparent !important;
    color: #49454f !important;
    font-weight: 500 !important;
    padding: 0.75rem 1rem !important;
    border-bottom: 2px solid transparent !important;
    border-radius: 0 !important;
    transition: color 0.15s ease, border-color 0.15s ease !important;
}

.md-form-container .tab-layout .tab-button.active {
    color: #6750a4 !important;
    border-bottom-color: #6750a4 !important;
    font-weight: 600 !important;
}

.md-form-container .tab-layout .tab-button:hover {
    background: rgba(103, 80, 164, 0.08) !important;
}

.md-form-container .tab-layout .tab-panel {
    padding: 8px 0 !important;
}
</style>


    
<div class="md-field">
    <button type="submit" class="md-button md-button-filled">Submit</button>
</div>

</form>

</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
    // Material Design 3 form enhancements

    // Floating label functionality for outlined text fields
    function initializeFloatingLabels() {
        const textFields = document.querySelectorAll('.md-input, .md-textarea, .md-select');

        textFields.forEach(input => {
            const label = input.nextElementSibling;
            if (label && label.classList.contains('md-floating-label')) {

                // Check initial state
                function updateLabelState() {
                    const hasValue = input.value && input.value.trim() !== '';
                    const isFocused = document.activeElement === input;

                    if (hasValue || isFocused) {
                        label.style.transform = 'translateY(-28px) scale(0.75)';
                        label.style.color = isFocused ? '#6750a4' : '#49454f';
                        label.style.background = '#ffffff';
                        label.style.padding = '0 4px';
                    } else {
                        label.style.transform = 'translateY(0) scale(1)';
                        label.style.color = '#49454f';
                        label.style.background = 'transparent';
                        label.style.padding = '0';
                    }
                }

                // Set up event listeners
                input.addEventListener('focus', updateLabelState);
                input.addEventListener('blur', updateLabelState);
                input.addEventListener('input', updateLabelState);

                // Initial state check
                updateLabelState();
            }
        });
    }

    // Enhanced focus and blur effects
    const inputs = document.querySelectorAll('.md-input, .md-select, .md-textarea');
    inputs.forEach(input => {
        input.addEventListener('focus', function() {
            this.style.transform = 'scale(1.01)';
            this.style.transition = 'all 0.15s cubic-bezier(0.4, 0, 0.2, 1)';
        });

        input.addEventListener('blur', function() {
            this.style.transform = 'scale(1)';
        });
    });

    // Checkbox interactions with Material Design ripple effect
    const checkboxes = document.querySelectorAll('.md-checkbox');
    checkboxes.forEach(checkbox => {
        checkbox.addEventListener('change', function() {
            const container = this.closest('.md-checkbox-container');
            if (this.checked) {
                // Create ripple effect
                const ripple = document.createElement('div');
                ripple.style.position = 'absolute';
                ripple.style.borderRadius = '50%';
                ripple.style.background = 'rgba(103, 80, 164, 0.3)';
                ripple.style.width = '40px';
                ripple.style.height = '40px';
                ripple.style.left = '-11px';
                ripple.style.top = '-11px';
                ripple.style.pointerEvents = 'none';
                ripple.style.transform = 'scale(0)';
                ripple.style.transition = 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)';

                this.style.position = 'relative';
                this.appendChild(ripple);

                // Animate ripple
                setTimeout(() => {
                    ripple.style.transform = 'scale(1)';
                    setTimeout(() => {
                        ripple.style.opacity = '0';
                        setTimeout(() => {
                            if (ripple.parentNode) {
                                ripple.parentNode.removeChild(ripple);
                            }
                        }, 300);
                    }, 200);
                }, 10);
            }
        });
    });

    // Enhanced form validation with Material Design styling
    const form = document.querySelector('.md-form');
    if (form) {
        form.addEventListener('submit', function(e) {
            const requiredInputs = this.querySelectorAll('input[required], select[required], textarea[required]');
            let hasErrors = false;

            requiredInputs.forEach(input => {
                const value = input.type === 'checkbox' ? input.checked : input.value.trim();
                const fieldContainer = input.closest('.md-field');

                if (!value) {
                    input.classList.add('error');

                    // Add error styling to label
                    const label = input.nextElementSibling;
                    if (label && label.classList.contains('md-floating-label')) {
                        label.style.color = '#ba1a1a';
                    }

                    // Create or update error message
                    let errorDiv = fieldContainer.querySelector('.md-error-text');
                    if (!errorDiv) {
                        errorDiv = document.createElement('div');
                        errorDiv.className = 'md-error-text';
                        fieldContainer.appendChild(errorDiv);
                    }
                    errorDiv.textContent = 'This field is required';

                    hasErrors = true;
                } else {
                    input.classList.remove('error');

                    // Remove error styling from label
                    const label = input.nextElementSibling;
                    if (label && label.classList.contains('md-floating-label')) {
                        label.style.color = input === document.activeElement ? '#6750a4' : '#49454f';
                    }

                    // Remove error message if it was dynamically added
                    const errorDiv = fieldContainer.querySelector('.md-error-text');
                    if (errorDiv && errorDiv.textContent === 'This field is required') {
                        errorDiv.remove();
                    }
                }
            });

            if (hasErrors) {
                e.preventDefault();
                // Scroll to first error with smooth animation
                const firstError = this.querySelector('.error');
                if (firstError) {
                    firstError.scrollIntoView({
                        behavior: 'smooth',
                        block: 'center',
                        inline: 'nearest'
                    });
                    // Focus the field for better UX
                    setTimeout(() => {
                        firstError.focus();
                    }, 500);
                }
            }
        });

        // Real-time validation for better UX
        const allInputs = form.querySelectorAll('input, select, textarea');
        allInputs.forEach(input => {
            input.addEventListener('blur', function() {
                if (this.hasAttribute('required')) {
                    const value = this.type === 'checkbox' ? this.checked : this.value.trim();
                    const fieldContainer = this.closest('.md-field');

                    if (!value) {
                        this.classList.add('error');
                        const label = this.nextElementSibling;
                        if (label && label.classList.contains('md-floating-label')) {
                            label.style.color = '#ba1a1a';
                        }
                    } else {
                        this.classList.remove('error');
                        const label = this.nextElementSibling;
                        if (label && label.classList.contains('md-floating-label')) {
                            label.style.color = '#49454f';
                        }
                    }
                }
            });
        });
    }

    # Initialize floating labels
    initializeFloatingLabels();

    # Reinitialize for dynamically added content
    window.reinitializeMaterialForms = function() {
        initializeFloatingLabels();
    };
});
</script>


<script>
(function() {
    document.addEventListener('DOMContentLoaded', function() {
        // Prevent Enter key from submitting forms unless on submit button
        const forms = document.querySelectorAll('form.md-form, form.pydantic-form');
        forms.forEach(function(form) {
            form.addEventListener('keydown', function(e) {
                // Check if Enter key is pressed
                if (e.key === 'Enter' || e.keyCode === 13) {
                    const target = e.target;

                    // Allow Enter in textareas (for multi-line input)
                    if (target.tagName === 'TEXTAREA') {
                        return;
                    }

                    // Allow Enter on submit buttons
                    if (target.tagName === 'BUTTON' && target.type === 'submit') {
                        return;
                    }

                    // Allow Enter on input type="submit"
                    if (target.tagName === 'INPUT' && target.type === 'submit') {
                        return;
                    }

                    // Prevent form submission for all other cases
                    e.preventDefault();
                    return false;
                }
            });
        });
    });
})();
</script>
class LayoutDemonstrationForm(FormModel):
    """
    Create a tabbed layout using VerticalLayout, HorizontalLayout, TabbedLayout, and ListLayout as the tabs.

    This demonstrates how to use layout classes as field types in a Pydantic form.
    Each field represents a different layout type that can be rendered as a tab.
    """
    vertical_tab: VerticalFormLayout = FormField(
        VerticalFormLayout(),
        title="Personal Info",
        input_type="layout",
        help_text="Vertical layout demonstration"
    )

    horizontal_tab: HorizontalFormLayout = FormField(
        HorizontalFormLayout(),
        title="Contact Info",
        input_type="layout",
        help_text="Horizontal layout demonstration"
    )

    tabbed_tab: TabbedFormLayout = FormField(
        TabbedFormLayout(),
        title="Preferences",
        input_type="layout",
        help_text="Tabbed layout demonstration"
    )

    list_tab: ListFormLayout = FormField(
        ListFormLayout(),
        title="Task List",
        input_type="layout",
        help_text="List layout demonstration"
    )
{
  "description": "Create a tabbed layout using VerticalLayout, HorizontalLayout, TabbedLayout, and ListLayout as the tabs.\n\nThis demonstrates how to use layout classes as field types in a Pydantic form.\nEach field represents a different layout type that can be rendered as a tab.",
  "properties": {
    "vertical_tab": {
      "additionalProperties": true,
      "autofocus": false,
      "description": "Vertical layout demonstration",
      "disabled": false,
      "help_text": "Vertical layout demonstration",
      "input_type": "layout",
      "readonly": false,
      "title": "Personal Info",
      "type": "object"
    },
    "horizontal_tab": {
      "additionalProperties": true,
      "autofocus": false,
      "description": "Horizontal layout demonstration",
      "disabled": false,
      "help_text": "Horizontal layout demonstration",
      "input_type": "layout",
      "readonly": false,
      "title": "Contact Info",
      "type": "object"
    },
    "tabbed_tab": {
      "additionalProperties": true,
      "autofocus": false,
      "description": "Tabbed layout demonstration",
      "disabled": false,
      "help_text": "Tabbed layout demonstration",
      "input_type": "layout",
      "readonly": false,
      "title": "Preferences",
      "type": "object"
    },
    "list_tab": {
      "additionalProperties": true,
      "autofocus": false,
      "description": "List layout demonstration",
      "disabled": false,
      "help_text": "List layout demonstration",
      "input_type": "layout",
      "readonly": false,
      "title": "Task List",
      "type": "object"
    }
  },
  "title": "LayoutDemonstrationForm",
  "type": "object"
}
{
  "vertical_tab": {
    "required": false,
    "type": "object"
  },
  "horizontal_tab": {
    "required": false,
    "type": "object"
  },
  "tabbed_tab": {
    "required": false,
    "type": "object"
  },
  "list_tab": {
    "required": false,
    "type": "object"
  }
}
{
  "errors": {},
  "data": {
    "vertical_tab": {
      "first_name": "Alex",
      "last_name": "Johnson",
      "email": "alex.johnson@example.com",
      "birth_date": "1990-05-15"
    },
    "horizontal_tab": {
      "phone": "+1 (555) 987-6543",
      "address": "456 Demo Street",
      "city": "San Francisco",
      "postal_code": "94102"
    },
    "tabbed_tab": {
      "notification_email": true,
      "notification_sms": false,
      "theme": "dark",
      "language": "en"
    },
    "list_tab": {
      "project_name": "Website Redesign Project",
      "tasks": [
        {
          "task_name": "Complete project setup and requirements gathering",
          "priority": "high",
          "due_date": "2024-12-01",
          "completed": false
        },
        {
          "task_name": "Design mockups and wireframes",
          "priority": "medium",
          "due_date": "2024-12-15",
          "completed": false
        }
      ]
    }
  }
}
Try Different Styles
API Endpoints Available
Schema: GET /api/forms/layouts/schema
Render: GET /api/forms/layouts/render
Submit: POST /api/forms/layouts/submit